diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:28:47 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:28:47 -0800 |
commit | adc854b798c1cfe3bfd4c27d68d5cee38ca617da (patch) | |
tree | 6aed8b4923ca428942cbaa7e848d50237a3d31e0 /concurrent/src/test/java/tests | |
parent | 1c0fed63c71ddb230f3b304aac12caffbedf2f21 (diff) | |
download | libcore-adc854b798c1cfe3bfd4c27d68d5cee38ca617da.zip libcore-adc854b798c1cfe3bfd4c27d68d5cee38ca617da.tar.gz libcore-adc854b798c1cfe3bfd4c27d68d5cee38ca617da.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'concurrent/src/test/java/tests')
44 files changed, 22413 insertions, 0 deletions
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractExecutorServiceTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractExecutorServiceTest.java new file mode 100644 index 0000000..99a007a --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractExecutorServiceTest.java @@ -0,0 +1,808 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.*; +import java.util.concurrent.*; +import java.math.BigInteger; +import java.security.*; + +public class AbstractExecutorServiceTest extends JSR166TestCase{ + public static void main(String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(AbstractExecutorServiceTest.class); + } + + /** + * A no-frills implementation of AbstractExecutorService, designed + * to test the submit methods only. + */ + static class DirectExecutorService extends AbstractExecutorService { + public void execute(Runnable r) { r.run(); } + public void shutdown() { shutdown = true; } + public List<Runnable> shutdownNow() { shutdown = true; return Collections.EMPTY_LIST; } + public boolean isShutdown() { return shutdown; } + public boolean isTerminated() { return isShutdown(); } + public boolean awaitTermination(long timeout, TimeUnit unit) { return isShutdown(); } + private volatile boolean shutdown = false; + } + + /** + * execute(runnable) runs it to completion + */ + public void testExecuteRunnable() { + try { + ExecutorService e = new DirectExecutorService(); + TrackedShortRunnable task = new TrackedShortRunnable(); + assertFalse(task.done); + Future<?> future = e.submit(task); + future.get(); + assertTrue(task.done); + } + catch (ExecutionException ex) { + unexpectedException(); + } + catch (InterruptedException ex) { + unexpectedException(); + } + } + + + /** + * Completed submit(callable) returns result + */ + public void testSubmitCallable() { + try { + ExecutorService e = new DirectExecutorService(); + Future<String> future = e.submit(new StringTask()); + String result = future.get(); + assertSame(TEST_STRING, result); + } + catch (ExecutionException ex) { + unexpectedException(); + } + catch (InterruptedException ex) { + unexpectedException(); + } + } + + /** + * Completed submit(runnable) returns successfully + */ + public void testSubmitRunnable() { + try { + ExecutorService e = new DirectExecutorService(); + Future<?> future = e.submit(new NoOpRunnable()); + future.get(); + assertTrue(future.isDone()); + } + catch (ExecutionException ex) { + unexpectedException(); + } + catch (InterruptedException ex) { + unexpectedException(); + } + } + + /** + * Completed submit(runnable, result) returns result + */ + public void testSubmitRunnable2() { + try { + ExecutorService e = new DirectExecutorService(); + Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING); + String result = future.get(); + assertSame(TEST_STRING, result); + } + catch (ExecutionException ex) { + unexpectedException(); + } + catch (InterruptedException ex) { + unexpectedException(); + } + } + + + /** + * A submitted privileged action to completion + */ + public void testSubmitPrivilegedAction() { + Policy savedPolicy = null; + try { + savedPolicy = Policy.getPolicy(); + AdjustablePolicy policy = new AdjustablePolicy(); + policy.addPermission(new RuntimePermission("getContextClassLoader")); + policy.addPermission(new RuntimePermission("setContextClassLoader")); + Policy.setPolicy(policy); + } catch(AccessControlException ok) { + return; + } + try { + ExecutorService e = new DirectExecutorService(); + Future future = e.submit(Executors.callable(new PrivilegedAction() { + public Object run() { + return TEST_STRING; + }})); + + Object result = future.get(); + assertSame(TEST_STRING, result); + } + catch (ExecutionException ex) { + unexpectedException(); + } + catch (InterruptedException ex) { + unexpectedException(); + } + finally { + try { + Policy.setPolicy(savedPolicy); + } catch(AccessControlException ok) { + return; + } + } + } + + /** + * A submitted a privileged exception action runs to completion + */ + public void testSubmitPrivilegedExceptionAction() { + Policy savedPolicy = null; + try { + savedPolicy = Policy.getPolicy(); + AdjustablePolicy policy = new AdjustablePolicy(); + policy.addPermission(new RuntimePermission("getContextClassLoader")); + policy.addPermission(new RuntimePermission("setContextClassLoader")); + Policy.setPolicy(policy); + } catch(AccessControlException ok) { + return; + } + + try { + ExecutorService e = new DirectExecutorService(); + Future future = e.submit(Executors.callable(new PrivilegedExceptionAction() { + public Object run() { + return TEST_STRING; + }})); + + Object result = future.get(); + assertSame(TEST_STRING, result); + } + catch (ExecutionException ex) { + unexpectedException(); + } + catch (InterruptedException ex) { + unexpectedException(); + } + finally { + Policy.setPolicy(savedPolicy); + } + } + + /** + * A submitted failed privileged exception action reports exception + */ + public void testSubmitFailedPrivilegedExceptionAction() { + Policy savedPolicy = null; + try { + savedPolicy = Policy.getPolicy(); + AdjustablePolicy policy = new AdjustablePolicy(); + policy.addPermission(new RuntimePermission("getContextClassLoader")); + policy.addPermission(new RuntimePermission("setContextClassLoader")); + Policy.setPolicy(policy); + } catch(AccessControlException ok) { + return; + } + + + try { + ExecutorService e = new DirectExecutorService(); + Future future = e.submit(Executors.callable(new PrivilegedExceptionAction() { + public Object run() throws Exception { + throw new IndexOutOfBoundsException(); + }})); + + Object result = future.get(); + shouldThrow(); + } + catch (ExecutionException success) { + } + catch (InterruptedException ex) { + unexpectedException(); + } + finally { + Policy.setPolicy(savedPolicy); + } + } + + /** + * execute(null runnable) throws NPE + */ + public void testExecuteNullRunnable() { + try { + ExecutorService e = new DirectExecutorService(); + TrackedShortRunnable task = null; + Future<?> future = e.submit(task); + shouldThrow(); + } + catch (NullPointerException success) { + } + catch (Exception ex) { + unexpectedException(); + } + } + + + /** + * submit(null callable) throws NPE + */ + public void testSubmitNullCallable() { + try { + ExecutorService e = new DirectExecutorService(); + StringTask t = null; + Future<String> future = e.submit(t); + shouldThrow(); + } + catch (NullPointerException success) { + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * submit(runnable) throws RejectedExecutionException if + * executor is saturated. + */ + public void testExecute1() { + ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1)); + try { + + for(int i = 0; i < 5; ++i){ + p.submit(new MediumRunnable()); + } + shouldThrow(); + } catch(RejectedExecutionException success){} + joinPool(p); + } + + /** + * submit(callable) throws RejectedExecutionException + * if executor is saturated. + */ + public void testExecute2() { + ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1)); + try { + for(int i = 0; i < 5; ++i) { + p.submit(new SmallCallable()); + } + shouldThrow(); + } catch(RejectedExecutionException e){} + joinPool(p); + } + + + /** + * Blocking on submit(callable) throws InterruptedException if + * caller interrupted. + */ + public void testInterruptedSubmit() { + final ThreadPoolExecutor p = new ThreadPoolExecutor(1,1,60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10)); + Thread t = new Thread(new Runnable() { + public void run() { + try { + p.submit(new Callable<Object>() { + public Object call() { + try { + Thread.sleep(MEDIUM_DELAY_MS); + shouldThrow(); + } catch(InterruptedException e){ + } + return null; + } + }).get(); + } catch(InterruptedException success){ + } catch(Exception e) { + unexpectedException(); + } + + } + }); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + } catch(Exception e){ + unexpectedException(); + } + joinPool(p); + } + + /** + * get of submitted callable throws Exception if callable + * interrupted + */ + public void testSubmitIE() { + final ThreadPoolExecutor p = new ThreadPoolExecutor(1,1,60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10)); + + final Callable c = new Callable() { + public Object call() { + try { + p.submit(new SmallCallable()).get(); + shouldThrow(); + } catch(InterruptedException e){} + catch(RejectedExecutionException e2){} + catch(ExecutionException e3){} + return Boolean.TRUE; + } + }; + + + + Thread t = new Thread(new Runnable() { + public void run() { + try { + c.call(); + } catch(Exception e){} + } + }); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } catch(InterruptedException e){ + unexpectedException(); + } + + joinPool(p); + } + + /** + * get of submit(callable) throws ExecutionException if callable + * throws exception + */ + public void testSubmitEE() { + ThreadPoolExecutor p = new ThreadPoolExecutor(1,1,60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10)); + + try { + Callable c = new Callable() { + public Object call() { + int i = 5/0; + return Boolean.TRUE; + } + }; + + for(int i =0; i < 5; i++){ + p.submit(c).get(); + } + + shouldThrow(); + } + catch(ExecutionException success){ + } catch(Exception e) { + unexpectedException(); + } + joinPool(p); + } + + /** + * invokeAny(null) throws NPE + */ + public void testInvokeAny1() { + ExecutorService e = new DirectExecutorService(); + try { + e.invokeAny(null); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * invokeAny(empty collection) throws IAE + */ + public void testInvokeAny2() { + ExecutorService e = new DirectExecutorService(); + try { + e.invokeAny(new ArrayList<Callable<String>>()); + } catch (IllegalArgumentException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * invokeAny(c) throws NPE if c has null elements + */ + public void testInvokeAny3() { + ExecutorService e = new DirectExecutorService(); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + l.add(null); + e.invokeAny(l); + } catch (NullPointerException success) { + } catch(Exception ex) { + ex.printStackTrace(); + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * invokeAny(c) throws ExecutionException if no task in c completes + */ + public void testInvokeAny4() { + ExecutorService e = new DirectExecutorService(); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new NPETask()); + e.invokeAny(l); + } catch(ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * invokeAny(c) returns result of some task in c if at least one completes + */ + public void testInvokeAny5() { + ExecutorService e = new DirectExecutorService(); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + l.add(new StringTask()); + String result = e.invokeAny(l); + assertSame(TEST_STRING, result); + } catch (ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * invokeAll(null) throws NPE + */ + public void testInvokeAll1() { + ExecutorService e = new DirectExecutorService(); + try { + e.invokeAll(null); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * invokeAll(empty collection) returns empty collection + */ + public void testInvokeAll2() { + ExecutorService e = new DirectExecutorService(); + try { + List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>()); + assertTrue(r.isEmpty()); + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * invokeAll(c) throws NPE if c has null elements + */ + public void testInvokeAll3() { + ExecutorService e = new DirectExecutorService(); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + l.add(null); + e.invokeAll(l); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * get of returned element of invokeAll(c) throws exception on failed task + */ + public void testInvokeAll4() { + ExecutorService e = new DirectExecutorService(); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new NPETask()); + List<Future<String>> result = e.invokeAll(l); + assertEquals(1, result.size()); + for (Iterator<Future<String>> it = result.iterator(); it.hasNext();) + it.next().get(); + } catch(ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * invokeAll(c) returns results of all completed tasks in c + */ + public void testInvokeAll5() { + ExecutorService e = new DirectExecutorService(); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + l.add(new StringTask()); + List<Future<String>> result = e.invokeAll(l); + assertEquals(2, result.size()); + for (Iterator<Future<String>> it = result.iterator(); it.hasNext();) + assertSame(TEST_STRING, it.next().get()); + } catch (ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + + /** + * timed invokeAny(null) throws NPE + */ + public void testTimedInvokeAny1() { + ExecutorService e = new DirectExecutorService(); + try { + e.invokeAny(null, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAny(null time unit) throws NPE + */ + public void testTimedInvokeAnyNullTimeUnit() { + ExecutorService e = new DirectExecutorService(); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + e.invokeAny(l, MEDIUM_DELAY_MS, null); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAny(empty collection) throws IAE + */ + public void testTimedInvokeAny2() { + ExecutorService e = new DirectExecutorService(); + try { + e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + } catch (IllegalArgumentException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAny(c) throws NPE if c has null elements + */ + public void testTimedInvokeAny3() { + ExecutorService e = new DirectExecutorService(); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + l.add(null); + e.invokeAny(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + } catch (NullPointerException success) { + } catch(Exception ex) { + ex.printStackTrace(); + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAny(c) throws ExecutionException if no task completes + */ + public void testTimedInvokeAny4() { + ExecutorService e = new DirectExecutorService(); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new NPETask()); + e.invokeAny(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + } catch(ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAny(c) returns result of some task in c + */ + public void testTimedInvokeAny5() { + ExecutorService e = new DirectExecutorService(); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + l.add(new StringTask()); + String result = e.invokeAny(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + assertSame(TEST_STRING, result); + } catch (ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAll(null) throws NPE + */ + public void testTimedInvokeAll1() { + ExecutorService e = new DirectExecutorService(); + try { + e.invokeAll(null, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAll(null time unit) throws NPE + */ + public void testTimedInvokeAllNullTimeUnit() { + ExecutorService e = new DirectExecutorService(); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + e.invokeAll(l, MEDIUM_DELAY_MS, null); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAll(empty collection) returns empty collection + */ + public void testTimedInvokeAll2() { + ExecutorService e = new DirectExecutorService(); + try { + List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + assertTrue(r.isEmpty()); + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAll(c) throws NPE if c has null elements + */ + public void testTimedInvokeAll3() { + ExecutorService e = new DirectExecutorService(); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + l.add(null); + e.invokeAll(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * get of returned element of invokeAll(c) throws exception on failed task + */ + public void testTimedInvokeAll4() { + ExecutorService e = new DirectExecutorService(); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new NPETask()); + List<Future<String>> result = e.invokeAll(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + assertEquals(1, result.size()); + for (Iterator<Future<String>> it = result.iterator(); it.hasNext();) + it.next().get(); + } catch(ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAll(c) returns results of all completed tasks in c + */ + public void testTimedInvokeAll5() { + ExecutorService e = new DirectExecutorService(); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + l.add(new StringTask()); + List<Future<String>> result = e.invokeAll(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + assertEquals(2, result.size()); + for (Iterator<Future<String>> it = result.iterator(); it.hasNext();) + assertSame(TEST_STRING, it.next().get()); + } catch (ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAll cancels tasks not completed by timeout + */ + public void testTimedInvokeAll6() { + ExecutorService e = new DirectExecutorService(); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + l.add(Executors.callable(new MediumPossiblyInterruptedRunnable(), TEST_STRING)); + l.add(new StringTask()); + List<Future<String>> result = e.invokeAll(l, SMALL_DELAY_MS, TimeUnit.MILLISECONDS); + assertEquals(3, result.size()); + Iterator<Future<String>> it = result.iterator(); + Future<String> f1 = it.next(); + Future<String> f2 = it.next(); + Future<String> f3 = it.next(); + assertTrue(f1.isDone()); + assertFalse(f1.isCancelled()); + assertTrue(f2.isDone()); + assertTrue(f3.isDone()); + assertTrue(f3.isCancelled()); + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractQueueTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractQueueTest.java new file mode 100644 index 0000000..0251390 --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractQueueTest.java @@ -0,0 +1,187 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.*; +import java.util.concurrent.*; +import java.util.concurrent.locks.*; +import java.io.*; + +public class AbstractQueueTest extends JSR166TestCase { + public static void main(String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(AbstractQueueTest.class); + } + + static class Succeed extends AbstractQueue<Integer> { + public boolean offer(Integer x) { + if (x == null) throw new NullPointerException(); + return true; + } + public Integer peek() { return one; } + public Integer poll() { return one; } + public int size() { return 0; } + public Iterator iterator() { return null; } // not needed + } + + static class Fail extends AbstractQueue<Integer> { + public boolean offer(Integer x) { + if (x == null) throw new NullPointerException(); + return false; + } + public Integer peek() { return null; } + public Integer poll() { return null; } + public int size() { return 0; } + public Iterator iterator() { return null; } // not needed + } + + /** + * add returns true if offer succeeds + */ + public void testAddS() { + Succeed q = new Succeed(); + assertTrue(q.add(two)); + } + + /** + * add throws ISE true if offer fails + */ + public void testAddF() { + Fail q = new Fail(); + try { + q.add(one); + shouldThrow(); + } catch (IllegalStateException success) { + } + } + + /** + * add throws NPE if offer does + */ + public void testAddNPE() { + Succeed q = new Succeed(); + try { + q.add(null); + shouldThrow(); + } catch (NullPointerException success) { + } + } + + /** + * remove returns normally if poll succeeds + */ + public void testRemoveS() { + Succeed q = new Succeed(); + q.remove(); + } + + /** + * remove throws NSEE if poll returns null + */ + public void testRemoveF() { + Fail q = new Fail(); + try { + q.remove(); + shouldThrow(); + } catch (NoSuchElementException success) { + } + } + + + /** + * element returns normally if peek succeeds + */ + public void testElementS() { + Succeed q = new Succeed(); + q.element(); + } + + /** + * element throws NSEE if peek returns null + */ + public void testElementF() { + Fail q = new Fail(); + try { + q.element(); + shouldThrow(); + } catch (NoSuchElementException success) { + } + } + + /** + * addAll(null) throws NPE + */ + public void testAddAll1() { + try { + Succeed q = new Succeed(); + q.addAll(null); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * addAll(this) throws IAE + */ + public void testAddAllSelf() { + try { + Succeed q = new Succeed(); + q.addAll(q); + shouldThrow(); + } + catch (IllegalArgumentException success) {} + } + + + /** + * addAll of a collection with null elements throws NPE + */ + public void testAddAll2() { + try { + Succeed q = new Succeed(); + Integer[] ints = new Integer[SIZE]; + q.addAll(Arrays.asList(ints)); + shouldThrow(); + } + catch (NullPointerException success) {} + } + /** + * addAll of a collection with any null elements throws NPE after + * possibly adding some elements + */ + public void testAddAll3() { + try { + Succeed q = new Succeed(); + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE-1; ++i) + ints[i] = new Integer(i); + q.addAll(Arrays.asList(ints)); + shouldThrow(); + } + catch (NullPointerException success) {} + } + /** + * addAll throws ISE if an add fails + */ + public void testAddAll4() { + try { + Fail q = new Fail(); + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE; ++i) + ints[i] = new Integer(i); + q.addAll(Arrays.asList(ints)); + shouldThrow(); + } + catch (IllegalStateException success) {} + } + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractQueuedSynchronizerTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractQueuedSynchronizerTest.java new file mode 100644 index 0000000..eed8d3a --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractQueuedSynchronizerTest.java @@ -0,0 +1,1301 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.*; +import java.util.concurrent.*; +import java.util.concurrent.locks.*; +import java.io.*; + +public class AbstractQueuedSynchronizerTest extends JSR166TestCase { + public static void main(String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(AbstractQueuedSynchronizerTest.class); + } + + /** + * A simple mutex class, adapted from the + * AbstractQueuedSynchronizer javadoc. Exclusive acquire tests + * exercise this as a sample user extension. Other + * methods/features of AbstractQueuedSynchronizerTest are tested + * via other test classes, including those for ReentrantLock, + * ReentrantReadWriteLock, and Semaphore + */ + static class Mutex extends AbstractQueuedSynchronizer { + public boolean isHeldExclusively() { return getState() == 1; } + + public boolean tryAcquire(int acquires) { + assertTrue(acquires == 1); + return compareAndSetState(0, 1); + } + + public boolean tryRelease(int releases) { + if (getState() == 0) throw new IllegalMonitorStateException(); + setState(0); + return true; + } + + public AbstractQueuedSynchronizer.ConditionObject newCondition() { return new AbstractQueuedSynchronizer.ConditionObject(); } + + } + + + /** + * A simple latch class, to test shared mode. + */ + static class BooleanLatch extends AbstractQueuedSynchronizer { + public boolean isSignalled() { return getState() != 0; } + + public int tryAcquireShared(int ignore) { + return isSignalled()? 1 : -1; + } + + public boolean tryReleaseShared(int ignore) { + setState(1); + return true; + } + } + + /** + * A runnable calling acquireInterruptibly + */ + class InterruptibleSyncRunnable implements Runnable { + final Mutex sync; + InterruptibleSyncRunnable(Mutex l) { sync = l; } + public void run() { + try { + sync.acquireInterruptibly(1); + } catch(InterruptedException success){} + } + } + + + /** + * A runnable calling acquireInterruptibly that expects to be + * interrupted + */ + class InterruptedSyncRunnable implements Runnable { + final Mutex sync; + InterruptedSyncRunnable(Mutex l) { sync = l; } + public void run() { + try { + sync.acquireInterruptibly(1); + threadShouldThrow(); + } catch(InterruptedException success){} + } + } + + /** + * isHeldExclusively is false upon construction + */ + public void testIsHeldExclusively() { + Mutex rl = new Mutex(); + assertFalse(rl.isHeldExclusively()); + } + + /** + * acquiring released sync succeeds + */ + public void testAcquire() { + Mutex rl = new Mutex(); + rl.acquire(1); + assertTrue(rl.isHeldExclusively()); + rl.release(1); + assertFalse(rl.isHeldExclusively()); + } + + /** + * tryAcquire on an released sync succeeds + */ + public void testTryAcquire() { + Mutex rl = new Mutex(); + assertTrue(rl.tryAcquire(1)); + assertTrue(rl.isHeldExclusively()); + rl.release(1); + } + + /** + * hasQueuedThreads reports whether there are waiting threads + */ + public void testhasQueuedThreads() { + final Mutex sync = new Mutex(); + Thread t1 = new Thread(new InterruptedSyncRunnable(sync)); + Thread t2 = new Thread(new InterruptibleSyncRunnable(sync)); + try { + assertFalse(sync.hasQueuedThreads()); + sync.acquire(1); + t1.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(sync.hasQueuedThreads()); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(sync.hasQueuedThreads()); + t1.interrupt(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(sync.hasQueuedThreads()); + sync.release(1); + Thread.sleep(SHORT_DELAY_MS); + assertFalse(sync.hasQueuedThreads()); + t1.join(); + t2.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * isQueued(null) throws NPE + */ + public void testIsQueuedNPE() { + final Mutex sync = new Mutex(); + try { + sync.isQueued(null); + shouldThrow(); + } catch (NullPointerException success) { + } + } + + /** + * isQueued reports whether a thread is queued. + */ + public void testIsQueued() { + final Mutex sync = new Mutex(); + Thread t1 = new Thread(new InterruptedSyncRunnable(sync)); + Thread t2 = new Thread(new InterruptibleSyncRunnable(sync)); + try { + assertFalse(sync.isQueued(t1)); + assertFalse(sync.isQueued(t2)); + sync.acquire(1); + t1.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(sync.isQueued(t1)); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(sync.isQueued(t1)); + assertTrue(sync.isQueued(t2)); + t1.interrupt(); + Thread.sleep(SHORT_DELAY_MS); + assertFalse(sync.isQueued(t1)); + assertTrue(sync.isQueued(t2)); + sync.release(1); + Thread.sleep(SHORT_DELAY_MS); + assertFalse(sync.isQueued(t1)); + Thread.sleep(SHORT_DELAY_MS); + assertFalse(sync.isQueued(t2)); + t1.join(); + t2.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * getFirstQueuedThread returns first waiting thread or null if none + */ + public void testGetFirstQueuedThread() { + final Mutex sync = new Mutex(); + Thread t1 = new Thread(new InterruptedSyncRunnable(sync)); + Thread t2 = new Thread(new InterruptibleSyncRunnable(sync)); + try { + assertNull(sync.getFirstQueuedThread()); + sync.acquire(1); + t1.start(); + Thread.sleep(SHORT_DELAY_MS); + assertEquals(t1, sync.getFirstQueuedThread()); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + assertEquals(t1, sync.getFirstQueuedThread()); + t1.interrupt(); + Thread.sleep(SHORT_DELAY_MS); + Thread.sleep(SHORT_DELAY_MS); + assertEquals(t2, sync.getFirstQueuedThread()); + sync.release(1); + Thread.sleep(SHORT_DELAY_MS); + assertNull(sync.getFirstQueuedThread()); + t1.join(); + t2.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + + /** + * hasContended reports false if no thread has ever blocked, else true + */ + public void testHasContended() { + final Mutex sync = new Mutex(); + Thread t1 = new Thread(new InterruptedSyncRunnable(sync)); + Thread t2 = new Thread(new InterruptibleSyncRunnable(sync)); + try { + assertFalse(sync.hasContended()); + sync.acquire(1); + t1.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(sync.hasContended()); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(sync.hasContended()); + t1.interrupt(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(sync.hasContended()); + sync.release(1); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(sync.hasContended()); + t1.join(); + t2.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * getQueuedThreads includes waiting threads + */ + public void testGetQueuedThreads() { + final Mutex sync = new Mutex(); + Thread t1 = new Thread(new InterruptedSyncRunnable(sync)); + Thread t2 = new Thread(new InterruptibleSyncRunnable(sync)); + try { + assertTrue(sync.getQueuedThreads().isEmpty()); + sync.acquire(1); + assertTrue(sync.getQueuedThreads().isEmpty()); + t1.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(sync.getQueuedThreads().contains(t1)); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(sync.getQueuedThreads().contains(t1)); + assertTrue(sync.getQueuedThreads().contains(t2)); + t1.interrupt(); + Thread.sleep(SHORT_DELAY_MS); + assertFalse(sync.getQueuedThreads().contains(t1)); + assertTrue(sync.getQueuedThreads().contains(t2)); + sync.release(1); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(sync.getQueuedThreads().isEmpty()); + t1.join(); + t2.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * getExclusiveQueuedThreads includes waiting threads + */ + public void testGetExclusiveQueuedThreads() { + final Mutex sync = new Mutex(); + Thread t1 = new Thread(new InterruptedSyncRunnable(sync)); + Thread t2 = new Thread(new InterruptibleSyncRunnable(sync)); + try { + assertTrue(sync.getExclusiveQueuedThreads().isEmpty()); + sync.acquire(1); + assertTrue(sync.getExclusiveQueuedThreads().isEmpty()); + t1.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(sync.getExclusiveQueuedThreads().contains(t1)); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(sync.getExclusiveQueuedThreads().contains(t1)); + assertTrue(sync.getExclusiveQueuedThreads().contains(t2)); + t1.interrupt(); + Thread.sleep(SHORT_DELAY_MS); + assertFalse(sync.getExclusiveQueuedThreads().contains(t1)); + assertTrue(sync.getExclusiveQueuedThreads().contains(t2)); + sync.release(1); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(sync.getExclusiveQueuedThreads().isEmpty()); + t1.join(); + t2.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * getSharedQueuedThreads does not include exclusively waiting threads + */ + public void testGetSharedQueuedThreads() { + final Mutex sync = new Mutex(); + Thread t1 = new Thread(new InterruptedSyncRunnable(sync)); + Thread t2 = new Thread(new InterruptibleSyncRunnable(sync)); + try { + assertTrue(sync.getSharedQueuedThreads().isEmpty()); + sync.acquire(1); + assertTrue(sync.getSharedQueuedThreads().isEmpty()); + t1.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(sync.getSharedQueuedThreads().isEmpty()); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(sync.getSharedQueuedThreads().isEmpty()); + t1.interrupt(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(sync.getSharedQueuedThreads().isEmpty()); + sync.release(1); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(sync.getSharedQueuedThreads().isEmpty()); + t1.join(); + t2.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * tryAcquireNanos is interruptible. + */ + public void testInterruptedException2() { + final Mutex sync = new Mutex(); + sync.acquire(1); + Thread t = new Thread(new Runnable() { + public void run() { + try { + sync.tryAcquireNanos(1, MEDIUM_DELAY_MS * 1000 * 1000); + threadShouldThrow(); + } catch(InterruptedException success){} + } + }); + try { + t.start(); + t.interrupt(); + } catch(Exception e){ + unexpectedException(); + } + } + + + /** + * TryAcquire on exclusively held sync fails + */ + public void testTryAcquireWhenSynced() { + final Mutex sync = new Mutex(); + sync.acquire(1); + Thread t = new Thread(new Runnable() { + public void run() { + threadAssertFalse(sync.tryAcquire(1)); + } + }); + try { + t.start(); + t.join(); + sync.release(1); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * tryAcquireNanos on an exclusively held sync times out + */ + public void testAcquireNanos_Timeout() { + final Mutex sync = new Mutex(); + sync.acquire(1); + Thread t = new Thread(new Runnable() { + public void run() { + try { + threadAssertFalse(sync.tryAcquireNanos(1, 1000 * 1000)); + } catch (Exception ex) { + threadUnexpectedException(); + } + } + }); + try { + t.start(); + t.join(); + sync.release(1); + } catch(Exception e){ + unexpectedException(); + } + } + + + /** + * getState is true when acquired and false when not + */ + public void testGetState() { + final Mutex sync = new Mutex(); + sync.acquire(1); + assertTrue(sync.isHeldExclusively()); + sync.release(1); + assertFalse(sync.isHeldExclusively()); + Thread t = new Thread(new Runnable() { + public void run() { + sync.acquire(1); + try { + Thread.sleep(SMALL_DELAY_MS); + } + catch(Exception e) { + threadUnexpectedException(); + } + sync.release(1); + } + }); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(sync.isHeldExclusively()); + t.join(); + assertFalse(sync.isHeldExclusively()); + } catch(Exception e){ + unexpectedException(); + } + } + + + /** + * acquireInterruptibly is interruptible. + */ + public void testAcquireInterruptibly1() { + final Mutex sync = new Mutex(); + sync.acquire(1); + Thread t = new Thread(new InterruptedSyncRunnable(sync)); + try { + t.start(); + t.interrupt(); + sync.release(1); + t.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * acquireInterruptibly succeeds when released, else is interruptible + */ + public void testAcquireInterruptibly2() { + final Mutex sync = new Mutex(); + try { + sync.acquireInterruptibly(1); + } catch(Exception e) { + unexpectedException(); + } + Thread t = new Thread(new InterruptedSyncRunnable(sync)); + try { + t.start(); + t.interrupt(); + assertTrue(sync.isHeldExclusively()); + t.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * owns is true for a condition created by sync else false + */ + public void testOwns() { + final Mutex sync = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition(); + final Mutex sync2 = new Mutex(); + assertTrue(sync.owns(c)); + assertFalse(sync2.owns(c)); + } + + /** + * Calling await without holding sync throws IllegalMonitorStateException + */ + public void testAwait_IllegalMonitor() { + final Mutex sync = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition(); + try { + c.await(); + shouldThrow(); + } + catch (IllegalMonitorStateException success) { + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * Calling signal without holding sync throws IllegalMonitorStateException + */ + public void testSignal_IllegalMonitor() { + final Mutex sync = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition(); + try { + c.signal(); + shouldThrow(); + } + catch (IllegalMonitorStateException success) { + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * awaitNanos without a signal times out + */ + public void testAwaitNanos_Timeout() { + final Mutex sync = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition(); + try { + sync.acquire(1); + long t = c.awaitNanos(100); + assertTrue(t <= 0); + sync.release(1); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * Timed await without a signal times out + */ + public void testAwait_Timeout() { + final Mutex sync = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition(); + try { + sync.acquire(1); + assertFalse(c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + sync.release(1); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * awaitUntil without a signal times out + */ + public void testAwaitUntil_Timeout() { + final Mutex sync = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition(); + try { + sync.acquire(1); + java.util.Date d = new java.util.Date(); + assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10))); + sync.release(1); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * await returns when signalled + */ + public void testAwait() { + final Mutex sync = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + sync.acquire(1); + c.await(); + sync.release(1); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + sync.acquire(1); + c.signal(); + sync.release(1); + t.join(SHORT_DELAY_MS); + assertFalse(t.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + + + /** + * hasWaiters throws NPE if null + */ + public void testHasWaitersNPE() { + final Mutex sync = new Mutex(); + try { + sync.hasWaiters(null); + shouldThrow(); + } catch (NullPointerException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + /** + * getWaitQueueLength throws NPE if null + */ + public void testGetWaitQueueLengthNPE() { + final Mutex sync = new Mutex(); + try { + sync.getWaitQueueLength(null); + shouldThrow(); + } catch (NullPointerException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + + /** + * getWaitingThreads throws NPE if null + */ + public void testGetWaitingThreadsNPE() { + final Mutex sync = new Mutex(); + try { + sync.getWaitingThreads(null); + shouldThrow(); + } catch (NullPointerException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + + /** + * hasWaiters throws IAE if not owned + */ + public void testHasWaitersIAE() { + final Mutex sync = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition()); + final Mutex sync2 = new Mutex(); + try { + sync2.hasWaiters(c); + shouldThrow(); + } catch (IllegalArgumentException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + /** + * hasWaiters throws IMSE if not synced + */ + public void testHasWaitersIMSE() { + final Mutex sync = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition()); + try { + sync.hasWaiters(c); + shouldThrow(); + } catch (IllegalMonitorStateException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + + /** + * getWaitQueueLength throws IAE if not owned + */ + public void testGetWaitQueueLengthIAE() { + final Mutex sync = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition()); + final Mutex sync2 = new Mutex(); + try { + sync2.getWaitQueueLength(c); + shouldThrow(); + } catch (IllegalArgumentException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + /** + * getWaitQueueLength throws IMSE if not synced + */ + public void testGetWaitQueueLengthIMSE() { + final Mutex sync = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition()); + try { + sync.getWaitQueueLength(c); + shouldThrow(); + } catch (IllegalMonitorStateException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + + /** + * getWaitingThreads throws IAE if not owned + */ + public void testGetWaitingThreadsIAE() { + final Mutex sync = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition()); + final Mutex sync2 = new Mutex(); + try { + sync2.getWaitingThreads(c); + shouldThrow(); + } catch (IllegalArgumentException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + /** + * getWaitingThreads throws IMSE if not synced + */ + public void testGetWaitingThreadsIMSE() { + final Mutex sync = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition()); + try { + sync.getWaitingThreads(c); + shouldThrow(); + } catch (IllegalMonitorStateException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + + + /** + * hasWaiters returns true when a thread is waiting, else false + */ + public void testHasWaiters() { + final Mutex sync = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + sync.acquire(1); + threadAssertFalse(sync.hasWaiters(c)); + threadAssertEquals(0, sync.getWaitQueueLength(c)); + c.await(); + sync.release(1); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + sync.acquire(1); + assertTrue(sync.hasWaiters(c)); + assertEquals(1, sync.getWaitQueueLength(c)); + c.signal(); + sync.release(1); + Thread.sleep(SHORT_DELAY_MS); + sync.acquire(1); + assertFalse(sync.hasWaiters(c)); + assertEquals(0, sync.getWaitQueueLength(c)); + sync.release(1); + t.join(SHORT_DELAY_MS); + assertFalse(t.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * getWaitQueueLength returns number of waiting threads + */ + public void testGetWaitQueueLength() { + final Mutex sync = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition(); + Thread t1 = new Thread(new Runnable() { + public void run() { + try { + sync.acquire(1); + threadAssertFalse(sync.hasWaiters(c)); + threadAssertEquals(0, sync.getWaitQueueLength(c)); + c.await(); + sync.release(1); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + Thread t2 = new Thread(new Runnable() { + public void run() { + try { + sync.acquire(1); + threadAssertTrue(sync.hasWaiters(c)); + threadAssertEquals(1, sync.getWaitQueueLength(c)); + c.await(); + sync.release(1); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + try { + t1.start(); + Thread.sleep(SHORT_DELAY_MS); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + sync.acquire(1); + assertTrue(sync.hasWaiters(c)); + assertEquals(2, sync.getWaitQueueLength(c)); + c.signalAll(); + sync.release(1); + Thread.sleep(SHORT_DELAY_MS); + sync.acquire(1); + assertFalse(sync.hasWaiters(c)); + assertEquals(0, sync.getWaitQueueLength(c)); + sync.release(1); + t1.join(SHORT_DELAY_MS); + t2.join(SHORT_DELAY_MS); + assertFalse(t1.isAlive()); + assertFalse(t2.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * getWaitingThreads returns only and all waiting threads + */ + public void testGetWaitingThreads() { + final Mutex sync = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition(); + Thread t1 = new Thread(new Runnable() { + public void run() { + try { + sync.acquire(1); + threadAssertTrue(sync.getWaitingThreads(c).isEmpty()); + c.await(); + sync.release(1); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + Thread t2 = new Thread(new Runnable() { + public void run() { + try { + sync.acquire(1); + threadAssertFalse(sync.getWaitingThreads(c).isEmpty()); + c.await(); + sync.release(1); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + try { + sync.acquire(1); + assertTrue(sync.getWaitingThreads(c).isEmpty()); + sync.release(1); + t1.start(); + Thread.sleep(SHORT_DELAY_MS); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + sync.acquire(1); + assertTrue(sync.hasWaiters(c)); + assertTrue(sync.getWaitingThreads(c).contains(t1)); + assertTrue(sync.getWaitingThreads(c).contains(t2)); + c.signalAll(); + sync.release(1); + Thread.sleep(SHORT_DELAY_MS); + sync.acquire(1); + assertFalse(sync.hasWaiters(c)); + assertTrue(sync.getWaitingThreads(c).isEmpty()); + sync.release(1); + t1.join(SHORT_DELAY_MS); + t2.join(SHORT_DELAY_MS); + assertFalse(t1.isAlive()); + assertFalse(t2.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + + + /** + * awaitUninterruptibly doesn't abort on interrupt + */ + public void testAwaitUninterruptibly() { + final Mutex sync = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition(); + Thread t = new Thread(new Runnable() { + public void run() { + sync.acquire(1); + c.awaitUninterruptibly(); + sync.release(1); + } + }); + + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + sync.acquire(1); + c.signal(); + sync.release(1); + assert(t.isInterrupted()); + t.join(SHORT_DELAY_MS); + assertFalse(t.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * await is interruptible + */ + public void testAwait_Interrupt() { + final Mutex sync = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + sync.acquire(1); + c.await(); + sync.release(1); + threadShouldThrow(); + } + catch(InterruptedException success) { + } + } + }); + + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(SHORT_DELAY_MS); + assertFalse(t.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * awaitNanos is interruptible + */ + public void testAwaitNanos_Interrupt() { + final Mutex sync = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + sync.acquire(1); + c.awaitNanos(1000 * 1000 * 1000); // 1 sec + sync.release(1); + threadShouldThrow(); + } + catch(InterruptedException success) { + } + } + }); + + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(SHORT_DELAY_MS); + assertFalse(t.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * awaitUntil is interruptible + */ + public void testAwaitUntil_Interrupt() { + final Mutex sync = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + sync.acquire(1); + java.util.Date d = new java.util.Date(); + c.awaitUntil(new java.util.Date(d.getTime() + 10000)); + sync.release(1); + threadShouldThrow(); + } + catch(InterruptedException success) { + } + } + }); + + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(SHORT_DELAY_MS); + assertFalse(t.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * signalAll wakes up all threads + */ + public void testSignalAll() { + final Mutex sync = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition(); + Thread t1 = new Thread(new Runnable() { + public void run() { + try { + sync.acquire(1); + c.await(); + sync.release(1); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + Thread t2 = new Thread(new Runnable() { + public void run() { + try { + sync.acquire(1); + c.await(); + sync.release(1); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + try { + t1.start(); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + sync.acquire(1); + c.signalAll(); + sync.release(1); + t1.join(SHORT_DELAY_MS); + t2.join(SHORT_DELAY_MS); + assertFalse(t1.isAlive()); + assertFalse(t2.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + + /** + * toString indicates current state + */ + public void testToString() { + Mutex sync = new Mutex(); + String us = sync.toString(); + assertTrue(us.indexOf("State = 0") >= 0); + sync.acquire(1); + String ls = sync.toString(); + assertTrue(ls.indexOf("State = 1") >= 0); + } + + /** + * A serialized AQS deserializes with current state + */ + public void testSerialization() { + Mutex l = new Mutex(); + l.acquire(1); + assertTrue(l.isHeldExclusively()); + + try { + ByteArrayOutputStream bout = new ByteArrayOutputStream(10000); + ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout)); + out.writeObject(l); + out.close(); + + ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); + ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin)); + Mutex r = (Mutex) in.readObject(); + assertTrue(r.isHeldExclusively()); + } catch(Exception e){ + e.printStackTrace(); + unexpectedException(); + } + } + + + /** + * tryReleaseShared setting state changes getState + */ + public void testGetStateWithReleaseShared() { + final BooleanLatch l = new BooleanLatch(); + assertFalse(l.isSignalled()); + l.releaseShared(0); + assertTrue(l.isSignalled()); + } + + /** + * releaseShared has no effect when already signalled + */ + public void testReleaseShared() { + final BooleanLatch l = new BooleanLatch(); + assertFalse(l.isSignalled()); + l.releaseShared(0); + assertTrue(l.isSignalled()); + l.releaseShared(0); + assertTrue(l.isSignalled()); + } + + /** + * acquireSharedInterruptibly returns after release, but not before + */ + public void testAcquireSharedInterruptibly() { + final BooleanLatch l = new BooleanLatch(); + + Thread t = new Thread(new Runnable() { + public void run() { + try { + threadAssertFalse(l.isSignalled()); + l.acquireSharedInterruptibly(0); + threadAssertTrue(l.isSignalled()); + } catch(InterruptedException e){ + threadUnexpectedException(); + } + } + }); + try { + t.start(); + assertFalse(l.isSignalled()); + Thread.sleep(SHORT_DELAY_MS); + l.releaseShared(0); + assertTrue(l.isSignalled()); + t.join(); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + + /** + * acquireSharedTimed returns after release + */ + public void testAsquireSharedTimed() { + final BooleanLatch l = new BooleanLatch(); + + Thread t = new Thread(new Runnable() { + public void run() { + try { + threadAssertFalse(l.isSignalled()); + threadAssertTrue(l.tryAcquireSharedNanos(0, MEDIUM_DELAY_MS* 1000 * 1000)); + threadAssertTrue(l.isSignalled()); + + } catch(InterruptedException e){ + threadUnexpectedException(); + } + } + }); + try { + t.start(); + assertFalse(l.isSignalled()); + Thread.sleep(SHORT_DELAY_MS); + l.releaseShared(0); + assertTrue(l.isSignalled()); + t.join(); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * acquireSharedInterruptibly throws IE if interrupted before released + */ + public void testAcquireSharedInterruptibly_InterruptedException() { + final BooleanLatch l = new BooleanLatch(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + threadAssertFalse(l.isSignalled()); + l.acquireSharedInterruptibly(0); + threadShouldThrow(); + } catch(InterruptedException success){} + } + }); + t.start(); + try { + assertFalse(l.isSignalled()); + t.interrupt(); + t.join(); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * acquireSharedTimed throws IE if interrupted before released + */ + public void testAcquireSharedNanos_InterruptedException() { + final BooleanLatch l = new BooleanLatch(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + threadAssertFalse(l.isSignalled()); + l.tryAcquireSharedNanos(0, SMALL_DELAY_MS* 1000 * 1000); + threadShouldThrow(); + } catch(InterruptedException success){} + } + }); + t.start(); + try { + Thread.sleep(SHORT_DELAY_MS); + assertFalse(l.isSignalled()); + t.interrupt(); + t.join(); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * acquireSharedTimed times out if not released before timeout + */ + public void testAcquireSharedNanos_Timeout() { + final BooleanLatch l = new BooleanLatch(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + threadAssertFalse(l.isSignalled()); + threadAssertFalse(l.tryAcquireSharedNanos(0, SMALL_DELAY_MS* 1000 * 1000)); + } catch(InterruptedException ie){ + threadUnexpectedException(); + } + } + }); + t.start(); + try { + Thread.sleep(SHORT_DELAY_MS); + assertFalse(l.isSignalled()); + t.join(); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ArrayBlockingQueueTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ArrayBlockingQueueTest.java new file mode 100755 index 0000000..da6988f --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ArrayBlockingQueueTest.java @@ -0,0 +1,1045 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.*; +import java.util.concurrent.*; +import java.io.*; + +public class ArrayBlockingQueueTest extends JSR166TestCase { + public static void main(String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(ArrayBlockingQueueTest.class); + } + + /** + * Create a queue of given size containing consecutive + * Integers 0 ... n. + */ + private ArrayBlockingQueue populatedQueue(int n) { + ArrayBlockingQueue q = new ArrayBlockingQueue(n); + assertTrue(q.isEmpty()); + for(int i = 0; i < n; i++) + assertTrue(q.offer(new Integer(i))); + assertFalse(q.isEmpty()); + assertEquals(0, q.remainingCapacity()); + assertEquals(n, q.size()); + return q; + } + + /** + * A new queue has the indicated capacity + */ + public void testConstructor1() { + assertEquals(SIZE, new ArrayBlockingQueue(SIZE).remainingCapacity()); + } + + /** + * Constructor throws IAE if capacity argument nonpositive + */ + public void testConstructor2() { + try { + ArrayBlockingQueue q = new ArrayBlockingQueue(0); + shouldThrow(); + } + catch (IllegalArgumentException success) {} + } + + /** + * Initializing from null Collection throws NPE + */ + public void testConstructor3() { + try { + ArrayBlockingQueue q = new ArrayBlockingQueue(1, true, null); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * Initializing from Collection of null elements throws NPE + */ + public void testConstructor4() { + try { + Integer[] ints = new Integer[SIZE]; + ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE, false, Arrays.asList(ints)); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * Initializing from Collection with some null elements throws NPE + */ + public void testConstructor5() { + try { + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE-1; ++i) + ints[i] = new Integer(i); + ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE, false, Arrays.asList(ints)); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * Initializing from too large collection throws IAE + */ + public void testConstructor6() { + try { + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE; ++i) + ints[i] = new Integer(i); + ArrayBlockingQueue q = new ArrayBlockingQueue(1, false, Arrays.asList(ints)); + shouldThrow(); + } + catch (IllegalArgumentException success) {} + } + + /** + * Queue contains all elements of collection used to initialize + */ + public void testConstructor7() { + try { + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE; ++i) + ints[i] = new Integer(i); + ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE, true, Arrays.asList(ints)); + for (int i = 0; i < SIZE; ++i) + assertEquals(ints[i], q.poll()); + } + finally {} + } + + /** + * Queue transitions from empty to full when elements added + */ + public void testEmptyFull() { + ArrayBlockingQueue q = new ArrayBlockingQueue(2); + assertTrue(q.isEmpty()); + assertEquals(2, q.remainingCapacity()); + q.add(one); + assertFalse(q.isEmpty()); + q.add(two); + assertFalse(q.isEmpty()); + assertEquals(0, q.remainingCapacity()); + assertFalse(q.offer(three)); + } + + /** + * remainingCapacity decreases on add, increases on remove + */ + public void testRemainingCapacity() { + ArrayBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.remainingCapacity()); + assertEquals(SIZE-i, q.size()); + q.remove(); + } + for (int i = 0; i < SIZE; ++i) { + assertEquals(SIZE-i, q.remainingCapacity()); + assertEquals(i, q.size()); + q.add(new Integer(i)); + } + } + + /** + * offer(null) throws NPE + */ + public void testOfferNull() { + try { + ArrayBlockingQueue q = new ArrayBlockingQueue(1); + q.offer(null); + shouldThrow(); + } catch (NullPointerException success) { } + } + + /** + * add(null) throws NPE + */ + public void testAddNull() { + try { + ArrayBlockingQueue q = new ArrayBlockingQueue(1); + q.add(null); + shouldThrow(); + } catch (NullPointerException success) { } + } + + /** + * Offer succeeds if not full; fails if full + */ + public void testOffer() { + ArrayBlockingQueue q = new ArrayBlockingQueue(1); + assertTrue(q.offer(zero)); + assertFalse(q.offer(one)); + } + + /** + * add succeeds if not full; throws ISE if full + */ + public void testAdd() { + try { + ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertTrue(q.add(new Integer(i))); + } + assertEquals(0, q.remainingCapacity()); + q.add(new Integer(SIZE)); + } catch (IllegalStateException success){ + } + } + + /** + * addAll(null) throws NPE + */ + public void testAddAll1() { + try { + ArrayBlockingQueue q = new ArrayBlockingQueue(1); + q.addAll(null); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * addAll(this) throws IAE + */ + public void testAddAllSelf() { + try { + ArrayBlockingQueue q = populatedQueue(SIZE); + q.addAll(q); + shouldThrow(); + } + catch (IllegalArgumentException success) {} + } + + + /** + * addAll of a collection with null elements throws NPE + */ + public void testAddAll2() { + try { + ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE); + Integer[] ints = new Integer[SIZE]; + q.addAll(Arrays.asList(ints)); + shouldThrow(); + } + catch (NullPointerException success) {} + } + /** + * addAll of a collection with any null elements throws NPE after + * possibly adding some elements + */ + public void testAddAll3() { + try { + ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE); + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE-1; ++i) + ints[i] = new Integer(i); + q.addAll(Arrays.asList(ints)); + shouldThrow(); + } + catch (NullPointerException success) {} + } + /** + * addAll throws ISE if not enough room + */ + public void testAddAll4() { + try { + ArrayBlockingQueue q = new ArrayBlockingQueue(1); + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE; ++i) + ints[i] = new Integer(i); + q.addAll(Arrays.asList(ints)); + shouldThrow(); + } + catch (IllegalStateException success) {} + } + /** + * Queue contains all elements, in traversal order, of successful addAll + */ + public void testAddAll5() { + try { + Integer[] empty = new Integer[0]; + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE; ++i) + ints[i] = new Integer(i); + ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE); + assertFalse(q.addAll(Arrays.asList(empty))); + assertTrue(q.addAll(Arrays.asList(ints))); + for (int i = 0; i < SIZE; ++i) + assertEquals(ints[i], q.poll()); + } + finally {} + } + + /** + * put(null) throws NPE + */ + public void testPutNull() { + try { + ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE); + q.put(null); + shouldThrow(); + } + catch (NullPointerException success){ + } + catch (InterruptedException ie) { + unexpectedException(); + } + } + + /** + * all elements successfully put are contained + */ + public void testPut() { + try { + ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + Integer I = new Integer(i); + q.put(I); + assertTrue(q.contains(I)); + } + assertEquals(0, q.remainingCapacity()); + } + catch (InterruptedException ie) { + unexpectedException(); + } + } + + /** + * put blocks interruptibly if full + */ + public void testBlockingPut() { + final ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE); + Thread t = new Thread(new Runnable() { + public void run() { + int added = 0; + try { + for (int i = 0; i < SIZE; ++i) { + q.put(new Integer(i)); + ++added; + } + q.put(new Integer(SIZE)); + threadShouldThrow(); + } catch (InterruptedException ie){ + threadAssertEquals(added, SIZE); + } + }}); + try { + t.start(); + Thread.sleep(MEDIUM_DELAY_MS); + t.interrupt(); + t.join(); + } + catch (InterruptedException ie) { + unexpectedException(); + } + } + + /** + * put blocks waiting for take when full + */ + public void testPutWithTake() { + final ArrayBlockingQueue q = new ArrayBlockingQueue(2); + Thread t = new Thread(new Runnable() { + public void run() { + int added = 0; + try { + q.put(new Object()); + ++added; + q.put(new Object()); + ++added; + q.put(new Object()); + ++added; + q.put(new Object()); + ++added; + threadShouldThrow(); + } catch (InterruptedException e){ + threadAssertTrue(added >= 2); + } + } + }); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + q.take(); + t.interrupt(); + t.join(); + } catch (Exception e){ + unexpectedException(); + } + } + + /** + * timed offer times out if full and elements not taken + */ + public void testTimedOffer() { + final ArrayBlockingQueue q = new ArrayBlockingQueue(2); + Thread t = new Thread(new Runnable() { + public void run() { + try { + q.put(new Object()); + q.put(new Object()); + threadAssertFalse(q.offer(new Object(), SHORT_DELAY_MS/2, TimeUnit.MILLISECONDS)); + q.offer(new Object(), LONG_DELAY_MS, TimeUnit.MILLISECONDS); + threadShouldThrow(); + } catch (InterruptedException success){} + } + }); + + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } catch (Exception e){ + unexpectedException(); + } + } + + /** + * take retrieves elements in FIFO order + */ + public void testTake() { + try { + ArrayBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.take()).intValue()); + } + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * take blocks interruptibly when empty + */ + public void testTakeFromEmpty() { + final ArrayBlockingQueue q = new ArrayBlockingQueue(2); + Thread t = new Thread(new Runnable() { + public void run() { + try { + q.take(); + threadShouldThrow(); + } catch (InterruptedException success){ } + } + }); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } catch (Exception e){ + unexpectedException(); + } + } + + /** + * Take removes existing elements until empty, then blocks interruptibly + */ + public void testBlockingTake() { + Thread t = new Thread(new Runnable() { + public void run() { + try { + ArrayBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + threadAssertEquals(i, ((Integer)q.take()).intValue()); + } + q.take(); + threadShouldThrow(); + } catch (InterruptedException success){ + } + }}); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } + catch (InterruptedException ie) { + unexpectedException(); + } + } + + + /** + * poll succeeds unless empty + */ + public void testPoll() { + ArrayBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.poll()).intValue()); + } + assertNull(q.poll()); + } + + /** + * timed pool with zero timeout succeeds when non-empty, else times out + */ + public void testTimedPoll0() { + try { + ArrayBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.poll(0, TimeUnit.MILLISECONDS)).intValue()); + } + assertNull(q.poll(0, TimeUnit.MILLISECONDS)); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * timed pool with nonzero timeout succeeds when non-empty, else times out + */ + public void testTimedPoll() { + try { + ArrayBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)).intValue()); + } + assertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * Interrupted timed poll throws InterruptedException instead of + * returning timeout status + */ + public void testInterruptedTimedPoll() { + Thread t = new Thread(new Runnable() { + public void run() { + try { + ArrayBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + threadAssertEquals(i, ((Integer)q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)).intValue()); + } + threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + } catch (InterruptedException success){ + } + }}); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } + catch (InterruptedException ie) { + unexpectedException(); + } + } + + /** + * timed poll before a delayed offer fails; after offer succeeds; + * on interruption throws + */ + public void testTimedPollWithOffer() { + final ArrayBlockingQueue q = new ArrayBlockingQueue(2); + Thread t = new Thread(new Runnable() { + public void run() { + try { + threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS); + q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS); + threadShouldThrow(); + } catch (InterruptedException success) { } + } + }); + try { + t.start(); + Thread.sleep(SMALL_DELAY_MS); + assertTrue(q.offer(zero, SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + t.interrupt(); + t.join(); + } catch (Exception e){ + unexpectedException(); + } + } + + + /** + * peek returns next element, or null if empty + */ + public void testPeek() { + ArrayBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.peek()).intValue()); + q.poll(); + assertTrue(q.peek() == null || + i != ((Integer)q.peek()).intValue()); + } + assertNull(q.peek()); + } + + /** + * element returns next element, or throws NSEE if empty + */ + public void testElement() { + ArrayBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.element()).intValue()); + q.poll(); + } + try { + q.element(); + shouldThrow(); + } + catch (NoSuchElementException success) {} + } + + /** + * remove removes next element, or throws NSEE if empty + */ + public void testRemove() { + ArrayBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.remove()).intValue()); + } + try { + q.remove(); + shouldThrow(); + } catch (NoSuchElementException success){ + } + } + + /** + * remove(x) removes x and returns true if present + */ + public void testRemoveElement() { + ArrayBlockingQueue q = populatedQueue(SIZE); + for (int i = 1; i < SIZE; i+=2) { + assertTrue(q.remove(new Integer(i))); + } + for (int i = 0; i < SIZE; i+=2) { + assertTrue(q.remove(new Integer(i))); + assertFalse(q.remove(new Integer(i+1))); + } + assertTrue(q.isEmpty()); + } + + /** + * contains(x) reports true when elements added but not yet removed + */ + public void testContains() { + ArrayBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertTrue(q.contains(new Integer(i))); + q.poll(); + assertFalse(q.contains(new Integer(i))); + } + } + + /** + * clear removes all elements + */ + public void testClear() { + ArrayBlockingQueue q = populatedQueue(SIZE); + q.clear(); + assertTrue(q.isEmpty()); + assertEquals(0, q.size()); + assertEquals(SIZE, q.remainingCapacity()); + q.add(one); + assertFalse(q.isEmpty()); + q.clear(); + assertTrue(q.isEmpty()); + } + + /** + * containsAll(c) is true when c contains a subset of elements + */ + public void testContainsAll() { + ArrayBlockingQueue q = populatedQueue(SIZE); + ArrayBlockingQueue p = new ArrayBlockingQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertTrue(q.containsAll(p)); + assertFalse(p.containsAll(q)); + p.add(new Integer(i)); + } + assertTrue(p.containsAll(q)); + } + + /** + * retainAll(c) retains only those elements of c and reports true if changed + */ + public void testRetainAll() { + ArrayBlockingQueue q = populatedQueue(SIZE); + ArrayBlockingQueue p = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + boolean changed = q.retainAll(p); + if (i == 0) + assertFalse(changed); + else + assertTrue(changed); + + assertTrue(q.containsAll(p)); + assertEquals(SIZE-i, q.size()); + p.remove(); + } + } + + /** + * removeAll(c) removes only those elements of c and reports true if changed + */ + public void testRemoveAll() { + for (int i = 1; i < SIZE; ++i) { + ArrayBlockingQueue q = populatedQueue(SIZE); + ArrayBlockingQueue p = populatedQueue(i); + assertTrue(q.removeAll(p)); + assertEquals(SIZE-i, q.size()); + for (int j = 0; j < i; ++j) { + Integer I = (Integer)(p.remove()); + assertFalse(q.contains(I)); + } + } + } + + /** + * toArray contains all elements + */ + public void testToArray() { + ArrayBlockingQueue q = populatedQueue(SIZE); + Object[] o = q.toArray(); + try { + for(int i = 0; i < o.length; i++) + assertEquals(o[i], q.take()); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * toArray(a) contains all elements + */ + public void testToArray2() { + ArrayBlockingQueue q = populatedQueue(SIZE); + Integer[] ints = new Integer[SIZE]; + ints = (Integer[])q.toArray(ints); + try { + for(int i = 0; i < ints.length; i++) + assertEquals(ints[i], q.take()); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * toArray(null) throws NPE + */ + public void testToArray_BadArg() { + try { + ArrayBlockingQueue q = populatedQueue(SIZE); + Object o[] = q.toArray(null); + shouldThrow(); + } catch(NullPointerException success){} + } + + /** + * toArray with incompatible array type throws CCE + */ + public void testToArray1_BadArg() { + try { + ArrayBlockingQueue q = populatedQueue(SIZE); + Object o[] = q.toArray(new String[10] ); + shouldThrow(); + } catch(ArrayStoreException success){} + } + + + /** + * iterator iterates through all elements + */ + public void testIterator() { + ArrayBlockingQueue q = populatedQueue(SIZE); + Iterator it = q.iterator(); + try { + while(it.hasNext()){ + assertEquals(it.next(), q.take()); + } + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * iterator.remove removes current element + */ + public void testIteratorRemove () { + final ArrayBlockingQueue q = new ArrayBlockingQueue(3); + q.add(two); + q.add(one); + q.add(three); + + Iterator it = q.iterator(); + it.next(); + it.remove(); + + it = q.iterator(); + assertEquals(it.next(), one); + assertEquals(it.next(), three); + assertFalse(it.hasNext()); + } + + /** + * iterator ordering is FIFO + */ + public void testIteratorOrdering() { + final ArrayBlockingQueue q = new ArrayBlockingQueue(3); + q.add(one); + q.add(two); + q.add(three); + + assertEquals("queue should be full", 0, q.remainingCapacity()); + + int k = 0; + for (Iterator it = q.iterator(); it.hasNext();) { + int i = ((Integer)(it.next())).intValue(); + assertEquals(++k, i); + } + assertEquals(3, k); + } + + /** + * Modifications do not cause iterators to fail + */ + public void testWeaklyConsistentIteration () { + final ArrayBlockingQueue q = new ArrayBlockingQueue(3); + q.add(one); + q.add(two); + q.add(three); + try { + for (Iterator it = q.iterator(); it.hasNext();) { + q.remove(); + it.next(); + } + } + catch (ConcurrentModificationException e) { + unexpectedException(); + } + assertEquals(0, q.size()); + } + + + /** + * toString contains toStrings of elements + */ + public void testToString() { + ArrayBlockingQueue q = populatedQueue(SIZE); + String s = q.toString(); + for (int i = 0; i < SIZE; ++i) { + assertTrue(s.indexOf(String.valueOf(i)) >= 0); + } + } + + + /** + * offer transfers elements across Executor tasks + */ + public void testOfferInExecutor() { + final ArrayBlockingQueue q = new ArrayBlockingQueue(2); + q.add(one); + q.add(two); + ExecutorService executor = Executors.newFixedThreadPool(2); + executor.execute(new Runnable() { + public void run() { + threadAssertFalse(q.offer(three)); + try { + threadAssertTrue(q.offer(three, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS)); + threadAssertEquals(0, q.remainingCapacity()); + } + catch (InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + executor.execute(new Runnable() { + public void run() { + try { + Thread.sleep(SMALL_DELAY_MS); + threadAssertEquals(one, q.take()); + } + catch (InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + joinPool(executor); + + } + + /** + * poll retrieves elements across Executor threads + */ + public void testPollInExecutor() { + final ArrayBlockingQueue q = new ArrayBlockingQueue(2); + ExecutorService executor = Executors.newFixedThreadPool(2); + executor.execute(new Runnable() { + public void run() { + threadAssertNull(q.poll()); + try { + threadAssertTrue(null != q.poll(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS)); + threadAssertTrue(q.isEmpty()); + } + catch (InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + executor.execute(new Runnable() { + public void run() { + try { + Thread.sleep(SMALL_DELAY_MS); + q.put(one); + } + catch (InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + joinPool(executor); + } + + /** + * A deserialized serialized queue has same elements in same order + */ + public void testSerialization() { + ArrayBlockingQueue q = populatedQueue(SIZE); + + try { + ByteArrayOutputStream bout = new ByteArrayOutputStream(10000); + ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout)); + out.writeObject(q); + out.close(); + + ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); + ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin)); + ArrayBlockingQueue r = (ArrayBlockingQueue)in.readObject(); + assertEquals(q.size(), r.size()); + while (!q.isEmpty()) + assertEquals(q.remove(), r.remove()); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * drainTo(null) throws NPE + */ + public void testDrainToNull() { + ArrayBlockingQueue q = populatedQueue(SIZE); + try { + q.drainTo(null); + shouldThrow(); + } catch(NullPointerException success) { + } + } + + /** + * drainTo(this) throws IAE + */ + public void testDrainToSelf() { + ArrayBlockingQueue q = populatedQueue(SIZE); + try { + q.drainTo(q); + shouldThrow(); + } catch(IllegalArgumentException success) { + } + } + + /** + * drainTo(c) empties queue into another collection c + */ + public void testDrainTo() { + ArrayBlockingQueue q = populatedQueue(SIZE); + ArrayList l = new ArrayList(); + q.drainTo(l); + assertEquals(q.size(), 0); + assertEquals(l.size(), SIZE); + for (int i = 0; i < SIZE; ++i) + assertEquals(l.get(i), new Integer(i)); + } + + /** + * drainTo empties full queue, unblocking a waiting put. + */ + public void testDrainToWithActivePut() { + final ArrayBlockingQueue q = populatedQueue(SIZE); + Thread t = new Thread(new Runnable() { + public void run() { + try { + q.put(new Integer(SIZE+1)); + } catch (InterruptedException ie){ + threadUnexpectedException(); + } + } + }); + try { + t.start(); + ArrayList l = new ArrayList(); + q.drainTo(l); + assertTrue(l.size() >= SIZE); + for (int i = 0; i < SIZE; ++i) + assertEquals(l.get(i), new Integer(i)); + t.join(); + assertTrue(q.size() + l.size() >= SIZE); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * drainTo(null, n) throws NPE + */ + public void testDrainToNullN() { + ArrayBlockingQueue q = populatedQueue(SIZE); + try { + q.drainTo(null, 0); + shouldThrow(); + } catch(NullPointerException success) { + } + } + + /** + * drainTo(this, n) throws IAE + */ + public void testDrainToSelfN() { + ArrayBlockingQueue q = populatedQueue(SIZE); + try { + q.drainTo(q, 0); + shouldThrow(); + } catch(IllegalArgumentException success) { + } + } + + /** + * drainTo(c, n) empties first max {n, size} elements of queue into c + */ + public void testDrainToN() { + for (int i = 0; i < SIZE + 2; ++i) { + ArrayBlockingQueue q = populatedQueue(SIZE); + ArrayList l = new ArrayList(); + q.drainTo(l, i); + int k = (i < SIZE)? i : SIZE; + assertEquals(q.size(), SIZE-k); + assertEquals(l.size(), k); + for (int j = 0; j < k; ++j) + assertEquals(l.get(j), new Integer(j)); + } + } + + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicBooleanTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicBooleanTest.java new file mode 100755 index 0000000..230357a --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicBooleanTest.java @@ -0,0 +1,146 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.concurrent.atomic.*; +import java.io.*; + +public class AtomicBooleanTest extends JSR166TestCase { + public static void main (String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(AtomicBooleanTest.class); + } + + /** + * constructor initializes to given value + */ + public void testConstructor() { + AtomicBoolean ai = new AtomicBoolean(true); + assertEquals(true,ai.get()); + } + + /** + * default constructed initializes to false + */ + public void testConstructor2() { + AtomicBoolean ai = new AtomicBoolean(); + assertEquals(false,ai.get()); + } + + /** + * get returns the last value set + */ + public void testGetSet() { + AtomicBoolean ai = new AtomicBoolean(true); + assertEquals(true,ai.get()); + ai.set(false); + assertEquals(false,ai.get()); + ai.set(true); + assertEquals(true,ai.get()); + + } + + /** + * compareAndSet succeeds in changing value if equal to expected else fails + */ + public void testCompareAndSet() { + AtomicBoolean ai = new AtomicBoolean(true); + assertTrue(ai.compareAndSet(true,false)); + assertEquals(false,ai.get()); + assertTrue(ai.compareAndSet(false,false)); + assertEquals(false,ai.get()); + assertFalse(ai.compareAndSet(true,false)); + assertFalse((ai.get())); + assertTrue(ai.compareAndSet(false,true)); + assertEquals(true,ai.get()); + } + + /** + * compareAndSet in one thread enables another waiting for value + * to succeed + */ + public void testCompareAndSetInMultipleThreads() { + final AtomicBoolean ai = new AtomicBoolean(true); + Thread t = new Thread(new Runnable() { + public void run() { + while(!ai.compareAndSet(false, true)) Thread.yield(); + }}); + try { + t.start(); + assertTrue(ai.compareAndSet(true, false)); + t.join(LONG_DELAY_MS); + assertFalse(t.isAlive()); + } + catch(Exception e) { + unexpectedException(); + } + } + + /** + * repeated weakCompareAndSet succeeds in changing value when equal + * to expected + */ + public void testWeakCompareAndSet() { + AtomicBoolean ai = new AtomicBoolean(true); + while(!ai.weakCompareAndSet(true,false)); + assertEquals(false,ai.get()); + while(!ai.weakCompareAndSet(false,false)); + assertEquals(false,ai.get()); + while(!ai.weakCompareAndSet(false,true)); + assertEquals(true,ai.get()); + } + + /** + * getAndSet returns previous value and sets to given value + */ + public void testGetAndSet() { + AtomicBoolean ai = new AtomicBoolean(true); + assertEquals(true,ai.getAndSet(false)); + assertEquals(false,ai.getAndSet(false)); + assertEquals(false,ai.getAndSet(true)); + assertEquals(true,ai.get()); + } + + /** + * a deserialized serialized atomic holds same value + */ + public void testSerialization() { + AtomicBoolean l = new AtomicBoolean(); + + try { + l.set(true); + ByteArrayOutputStream bout = new ByteArrayOutputStream(10000); + ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout)); + out.writeObject(l); + out.close(); + + ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); + ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin)); + AtomicBoolean r = (AtomicBoolean) in.readObject(); + assertEquals(l.get(), r.get()); + } catch(Exception e){ + e.printStackTrace(); + unexpectedException(); + } + } + + /** + * toString returns current value. + */ + public void testToString() { + AtomicBoolean ai = new AtomicBoolean(); + assertEquals(ai.toString(), Boolean.toString(false)); + ai.set(true); + assertEquals(ai.toString(), Boolean.toString(true)); + } + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerArrayTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerArrayTest.java new file mode 100644 index 0000000..cd13fcf --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerArrayTest.java @@ -0,0 +1,340 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.concurrent.atomic.*; +import java.io.*; +import java.util.*; + +public class AtomicIntegerArrayTest extends JSR166TestCase { + + public static void main (String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(AtomicIntegerArrayTest.class); + } + + + /** + * constructor creates array of given size with all elements zero + */ + public void testConstructor() { + AtomicIntegerArray ai = new AtomicIntegerArray(SIZE); + for (int i = 0; i < SIZE; ++i) + assertEquals(0,ai.get(i)); + } + + /** + * constructor with null array throws NPE + */ + public void testConstructor2NPE() { + try { + int[] a = null; + AtomicIntegerArray ai = new AtomicIntegerArray(a); + } catch (NullPointerException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + /** + * constructor with array is of same size and has all elements + */ + public void testConstructor2() { + int[] a = { 17, 3, -42, 99, -7}; + AtomicIntegerArray ai = new AtomicIntegerArray(a); + assertEquals(a.length, ai.length()); + for (int i = 0; i < a.length; ++i) + assertEquals(a[i], ai.get(i)); + } + + /** + * get and set for out of bound indices throw IndexOutOfBoundsException + */ + public void testIndexing(){ + AtomicIntegerArray ai = new AtomicIntegerArray(SIZE); + try { + ai.get(SIZE); + } catch(IndexOutOfBoundsException success){ + } + try { + ai.get(-1); + } catch(IndexOutOfBoundsException success){ + } + try { + ai.set(SIZE, 0); + } catch(IndexOutOfBoundsException success){ + } + try { + ai.set(-1, 0); + } catch(IndexOutOfBoundsException success){ + } + } + + /** + * get returns the last value set at index + */ + public void testGetSet() { + AtomicIntegerArray ai = new AtomicIntegerArray(SIZE); + for (int i = 0; i < SIZE; ++i) { + ai.set(i, 1); + assertEquals(1,ai.get(i)); + ai.set(i, 2); + assertEquals(2,ai.get(i)); + ai.set(i, -3); + assertEquals(-3,ai.get(i)); + } + } + + /** + * compareAndSet succeeds in changing value if equal to expected else fails + */ + public void testCompareAndSet() { + AtomicIntegerArray ai = new AtomicIntegerArray(SIZE); + for (int i = 0; i < SIZE; ++i) { + ai.set(i, 1); + assertTrue(ai.compareAndSet(i, 1,2)); + assertTrue(ai.compareAndSet(i, 2,-4)); + assertEquals(-4,ai.get(i)); + assertFalse(ai.compareAndSet(i, -5,7)); + assertFalse((7 == ai.get(i))); + assertTrue(ai.compareAndSet(i, -4,7)); + assertEquals(7,ai.get(i)); + } + } + + /** + * compareAndSet in one thread enables another waiting for value + * to succeed + */ + public void testCompareAndSetInMultipleThreads() { + final AtomicIntegerArray a = new AtomicIntegerArray(1); + a.set(0, 1); + Thread t = new Thread(new Runnable() { + public void run() { + while(!a.compareAndSet(0, 2, 3)) Thread.yield(); + }}); + try { + t.start(); + assertTrue(a.compareAndSet(0, 1, 2)); + t.join(LONG_DELAY_MS); + assertFalse(t.isAlive()); + assertEquals(a.get(0), 3); + } + catch(Exception e) { + unexpectedException(); + } + } + + /** + * repeated weakCompareAndSet succeeds in changing value when equal + * to expected + */ + public void testWeakCompareAndSet() { + AtomicIntegerArray ai = new AtomicIntegerArray(SIZE); + for (int i = 0; i < SIZE; ++i) { + ai.set(i, 1); + while(!ai.weakCompareAndSet(i, 1,2)); + while(!ai.weakCompareAndSet(i, 2,-4)); + assertEquals(-4,ai.get(i)); + while(!ai.weakCompareAndSet(i, -4,7)); + assertEquals(7,ai.get(i)); + } + } + + /** + * getAndSet returns previous value and sets to given value at given index + */ + public void testGetAndSet() { + AtomicIntegerArray ai = new AtomicIntegerArray(SIZE); + for (int i = 0; i < SIZE; ++i) { + ai.set(i, 1); + assertEquals(1,ai.getAndSet(i,0)); + assertEquals(0,ai.getAndSet(i,-10)); + assertEquals(-10,ai.getAndSet(i,1)); + } + } + + /** + * getAndAdd returns previous value and adds given value + */ + public void testGetAndAdd() { + AtomicIntegerArray ai = new AtomicIntegerArray(SIZE); + for (int i = 0; i < SIZE; ++i) { + ai.set(i, 1); + assertEquals(1,ai.getAndAdd(i,2)); + assertEquals(3,ai.get(i)); + assertEquals(3,ai.getAndAdd(i,-4)); + assertEquals(-1,ai.get(i)); + } + } + + /** + * getAndDecrement returns previous value and decrements + */ + public void testGetAndDecrement() { + AtomicIntegerArray ai = new AtomicIntegerArray(SIZE); + for (int i = 0; i < SIZE; ++i) { + ai.set(i, 1); + assertEquals(1,ai.getAndDecrement(i)); + assertEquals(0,ai.getAndDecrement(i)); + assertEquals(-1,ai.getAndDecrement(i)); + } + } + + /** + * getAndIncrement returns previous value and increments + */ + public void testGetAndIncrement() { + AtomicIntegerArray ai = new AtomicIntegerArray(SIZE); + for (int i = 0; i < SIZE; ++i) { + ai.set(i, 1); + assertEquals(1,ai.getAndIncrement(i)); + assertEquals(2,ai.get(i)); + ai.set(i,-2); + assertEquals(-2,ai.getAndIncrement(i)); + assertEquals(-1,ai.getAndIncrement(i)); + assertEquals(0,ai.getAndIncrement(i)); + assertEquals(1,ai.get(i)); + } + } + + /** + * addAndGet adds given value to current, and returns current value + */ + public void testAddAndGet() { + AtomicIntegerArray ai = new AtomicIntegerArray(SIZE); + for (int i = 0; i < SIZE; ++i) { + ai.set(i, 1); + assertEquals(3,ai.addAndGet(i,2)); + assertEquals(3,ai.get(i)); + assertEquals(-1,ai.addAndGet(i,-4)); + assertEquals(-1,ai.get(i)); + } + } + + /** + * decrementAndGet decrements and returns current value + */ + public void testDecrementAndGet() { + AtomicIntegerArray ai = new AtomicIntegerArray(SIZE); + for (int i = 0; i < SIZE; ++i) { + ai.set(i, 1); + assertEquals(0,ai.decrementAndGet(i)); + assertEquals(-1,ai.decrementAndGet(i)); + assertEquals(-2,ai.decrementAndGet(i)); + assertEquals(-2,ai.get(i)); + } + } + + /** + * incrementAndGet increments and returns current value + */ + public void testIncrementAndGet() { + AtomicIntegerArray ai = new AtomicIntegerArray(SIZE); + for (int i = 0; i < SIZE; ++i) { + ai.set(i, 1); + assertEquals(2,ai.incrementAndGet(i)); + assertEquals(2,ai.get(i)); + ai.set(i, -2); + assertEquals(-1,ai.incrementAndGet(i)); + assertEquals(0,ai.incrementAndGet(i)); + assertEquals(1,ai.incrementAndGet(i)); + assertEquals(1,ai.get(i)); + } + } + + static final int COUNTDOWN = 100000; + + class Counter implements Runnable { + final AtomicIntegerArray ai; + volatile int counts; + Counter(AtomicIntegerArray a) { ai = a; } + public void run() { + for (;;) { + boolean done = true; + for (int i = 0; i < ai.length(); ++i) { + int v = ai.get(i); + threadAssertTrue(v >= 0); + if (v != 0) { + done = false; + if (ai.compareAndSet(i, v, v-1)) + ++counts; + } + } + if (done) + break; + } + } + } + + /** + * Multiple threads using same array of counters successfully + * update a number of times equal to total count + */ + public void testCountingInMultipleThreads() { + try { + final AtomicIntegerArray ai = new AtomicIntegerArray(SIZE); + for (int i = 0; i < SIZE; ++i) + ai.set(i, COUNTDOWN); + Counter c1 = new Counter(ai); + Counter c2 = new Counter(ai); + Thread t1 = new Thread(c1); + Thread t2 = new Thread(c2); + t1.start(); + t2.start(); + t1.join(); + t2.join(); + assertEquals(c1.counts+c2.counts, SIZE * COUNTDOWN); + } + catch(InterruptedException ie) { + unexpectedException(); + } + } + + + /** + * a deserialized serialized array holds same values + */ + public void testSerialization() { + AtomicIntegerArray l = new AtomicIntegerArray(SIZE); + for (int i = 0; i < SIZE; ++i) + l.set(i, -i); + + try { + ByteArrayOutputStream bout = new ByteArrayOutputStream(10000); + ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout)); + out.writeObject(l); + out.close(); + + ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); + ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin)); + AtomicIntegerArray r = (AtomicIntegerArray) in.readObject(); + for (int i = 0; i < SIZE; ++i) { + assertEquals(l.get(i), r.get(i)); + } + } catch(Exception e){ + e.printStackTrace(); + unexpectedException(); + } + } + + + /** + * toString returns current value. + */ + public void testToString() { + int[] a = { 17, 3, -42, 99, -7}; + AtomicIntegerArray ai = new AtomicIntegerArray(a); + assertEquals(Arrays.toString(a), ai.toString()); + } + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerFieldUpdaterTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerFieldUpdaterTest.java new file mode 100755 index 0000000..03fd2c8 --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerFieldUpdaterTest.java @@ -0,0 +1,275 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import java.util.concurrent.atomic.*; +import junit.framework.*; +import java.util.*; + +public class AtomicIntegerFieldUpdaterTest extends JSR166TestCase { + volatile int x = 0; + int w; + long z; + public static void main(String[] args){ + junit.textui.TestRunner.run(suite()); + } + public static Test suite() { + return new TestSuite(AtomicIntegerFieldUpdaterTest.class); + } + + /** + * Construction with non-existent field throws RuntimeException + */ + public void testConstructor() { + try{ + AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> + a = AtomicIntegerFieldUpdater.newUpdater + (AtomicIntegerFieldUpdaterTest.class, "y"); + shouldThrow(); + } + catch (RuntimeException rt) {} + } + + /** + * construction with field not of given type throws RuntimeException + */ + public void testConstructor2() { + try{ + AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> + a = AtomicIntegerFieldUpdater.newUpdater + (AtomicIntegerFieldUpdaterTest.class, "z"); + shouldThrow(); + } + catch (RuntimeException rt) {} + } + + /** + * construction with non-volatile field throws RuntimeException + */ + public void testConstructor3() { + try{ + AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> + a = AtomicIntegerFieldUpdater.newUpdater + (AtomicIntegerFieldUpdaterTest.class, "w"); + shouldThrow(); + } + catch (RuntimeException rt) {} + } + + /** + * get returns the last value set or assigned + */ + public void testGetSet() { + AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; + try { + a = AtomicIntegerFieldUpdater.newUpdater(AtomicIntegerFieldUpdaterTest.class, "x"); + } catch (RuntimeException ok) { + return; + } + x = 1; + assertEquals(1,a.get(this)); + a.set(this,2); + assertEquals(2,a.get(this)); + a.set(this,-3); + assertEquals(-3,a.get(this)); + + } + /** + * compareAndSet succeeds in changing value if equal to expected else fails + */ + public void testCompareAndSet() { + AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; + try { + a = AtomicIntegerFieldUpdater.newUpdater(AtomicIntegerFieldUpdaterTest.class, "x"); + } catch (RuntimeException ok) { + return; + } + x = 1; + assertTrue(a.compareAndSet(this,1,2)); + assertTrue(a.compareAndSet(this,2,-4)); + assertEquals(-4,a.get(this)); + assertFalse(a.compareAndSet(this,-5,7)); + assertFalse((7 == a.get(this))); + assertTrue(a.compareAndSet(this,-4,7)); + assertEquals(7,a.get(this)); + } + + + /** + * compareAndSet in one thread enables another waiting for value + * to succeed + */ + public void testCompareAndSetInMultipleThreads() { + x = 1; + final AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest>a; + try { + a = AtomicIntegerFieldUpdater.newUpdater(AtomicIntegerFieldUpdaterTest.class, "x"); + } catch (RuntimeException ok) { + return; + } + + Thread t = new Thread(new Runnable() { + public void run() { + while(!a.compareAndSet(AtomicIntegerFieldUpdaterTest.this, 2, 3)) Thread.yield(); + }}); + try { + t.start(); + assertTrue(a.compareAndSet(this, 1, 2)); + t.join(LONG_DELAY_MS); + assertFalse(t.isAlive()); + assertEquals(a.get(this), 3); + } + catch(Exception e) { + unexpectedException(); + } + } + + /** + * repeated weakCompareAndSet succeeds in changing value when equal + * to expected + */ + public void testWeakCompareAndSet() { + AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; + try { + a = AtomicIntegerFieldUpdater.newUpdater(AtomicIntegerFieldUpdaterTest.class, "x"); + } catch (RuntimeException ok) { + return; + } + x = 1; + while(!a.weakCompareAndSet(this,1,2)); + while(!a.weakCompareAndSet(this,2,-4)); + assertEquals(-4,a.get(this)); + while(!a.weakCompareAndSet(this,-4,7)); + assertEquals(7,a.get(this)); + } + + /** + * getAndSet returns previous value and sets to given value + */ + public void testGetAndSet() { + AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; + try { + a = AtomicIntegerFieldUpdater.newUpdater(AtomicIntegerFieldUpdaterTest.class, "x"); + } catch (RuntimeException ok) { + return; + } + x = 1; + assertEquals(1,a.getAndSet(this, 0)); + assertEquals(0,a.getAndSet(this,-10)); + assertEquals(-10,a.getAndSet(this,1)); + } + + /** + * getAndAdd returns previous value and adds given value + */ + public void testGetAndAdd() { + AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; + try { + a = AtomicIntegerFieldUpdater.newUpdater(AtomicIntegerFieldUpdaterTest.class, "x"); + } catch (RuntimeException ok) { + return; + } + x = 1; + assertEquals(1,a.getAndAdd(this,2)); + assertEquals(3,a.get(this)); + assertEquals(3,a.getAndAdd(this,-4)); + assertEquals(-1,a.get(this)); + } + + /** + * getAndDecrement returns previous value and decrements + */ + public void testGetAndDecrement() { + AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; + try { + a = AtomicIntegerFieldUpdater.newUpdater(AtomicIntegerFieldUpdaterTest.class, "x"); + } catch (RuntimeException ok) { + return; + } + x = 1; + assertEquals(1,a.getAndDecrement(this)); + assertEquals(0,a.getAndDecrement(this)); + assertEquals(-1,a.getAndDecrement(this)); + } + + /** + * getAndIncrement returns previous value and increments + */ + public void testGetAndIncrement() { + AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; + try { + a = AtomicIntegerFieldUpdater.newUpdater(AtomicIntegerFieldUpdaterTest.class, "x"); + } catch (RuntimeException ok) { + return; + } + x = 1; + assertEquals(1,a.getAndIncrement(this)); + assertEquals(2,a.get(this)); + a.set(this,-2); + assertEquals(-2,a.getAndIncrement(this)); + assertEquals(-1,a.getAndIncrement(this)); + assertEquals(0,a.getAndIncrement(this)); + assertEquals(1,a.get(this)); + } + + /** + * addAndGet adds given value to current, and returns current value + */ + public void testAddAndGet() { + AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; + try { + a = AtomicIntegerFieldUpdater.newUpdater(AtomicIntegerFieldUpdaterTest.class, "x"); + } catch (RuntimeException ok) { + return; + } + x = 1; + assertEquals(3,a.addAndGet(this,2)); + assertEquals(3,a.get(this)); + assertEquals(-1,a.addAndGet(this,-4)); + assertEquals(-1,a.get(this)); + } + + /** + * decrementAndGet decrements and returns current value + */ + public void testDecrementAndGet() { + AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; + try { + a = AtomicIntegerFieldUpdater.newUpdater(AtomicIntegerFieldUpdaterTest.class, "x"); + } catch (RuntimeException ok) { + return; + } + x = 1; + assertEquals(0,a.decrementAndGet(this)); + assertEquals(-1,a.decrementAndGet(this)); + assertEquals(-2,a.decrementAndGet(this)); + assertEquals(-2,a.get(this)); + } + + /** + * incrementAndGet increments and returns current value + */ + public void testIncrementAndGet() { + AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; + try { + a = AtomicIntegerFieldUpdater.newUpdater(AtomicIntegerFieldUpdaterTest.class, "x"); + } catch (RuntimeException ok) { + return; + } + x = 1; + assertEquals(2,a.incrementAndGet(this)); + assertEquals(2,a.get(this)); + a.set(this,-2); + assertEquals(-1,a.incrementAndGet(this)); + assertEquals(0,a.incrementAndGet(this)); + assertEquals(1,a.incrementAndGet(this)); + assertEquals(1,a.get(this)); + } + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerTest.java new file mode 100755 index 0000000..1771d80 --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerTest.java @@ -0,0 +1,261 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.concurrent.atomic.*; +import java.io.*; + +public class AtomicIntegerTest extends JSR166TestCase { + public static void main (String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(AtomicIntegerTest.class); + } + + /** + * constructor initializes to given value + */ + public void testConstructor(){ + AtomicInteger ai = new AtomicInteger(1); + assertEquals(1,ai.get()); + } + + /** + * default constructed initializes to zero + */ + public void testConstructor2(){ + AtomicInteger ai = new AtomicInteger(); + assertEquals(0,ai.get()); + } + + /** + * get returns the last value set + */ + public void testGetSet(){ + AtomicInteger ai = new AtomicInteger(1); + assertEquals(1,ai.get()); + ai.set(2); + assertEquals(2,ai.get()); + ai.set(-3); + assertEquals(-3,ai.get()); + + } + /** + * compareAndSet succeeds in changing value if equal to expected else fails + */ + public void testCompareAndSet(){ + AtomicInteger ai = new AtomicInteger(1); + assertTrue(ai.compareAndSet(1,2)); + assertTrue(ai.compareAndSet(2,-4)); + assertEquals(-4,ai.get()); + assertFalse(ai.compareAndSet(-5,7)); + assertFalse((7 == ai.get())); + assertTrue(ai.compareAndSet(-4,7)); + assertEquals(7,ai.get()); + } + + /** + * compareAndSet in one thread enables another waiting for value + * to succeed + */ + public void testCompareAndSetInMultipleThreads() { + final AtomicInteger ai = new AtomicInteger(1); + Thread t = new Thread(new Runnable() { + public void run() { + while(!ai.compareAndSet(2, 3)) Thread.yield(); + }}); + try { + t.start(); + assertTrue(ai.compareAndSet(1, 2)); + t.join(LONG_DELAY_MS); + assertFalse(t.isAlive()); + assertEquals(ai.get(), 3); + } + catch(Exception e) { + unexpectedException(); + } + } + + /** + * repeated weakCompareAndSet succeeds in changing value when equal + * to expected + */ + public void testWeakCompareAndSet(){ + AtomicInteger ai = new AtomicInteger(1); + while(!ai.weakCompareAndSet(1,2)); + while(!ai.weakCompareAndSet(2,-4)); + assertEquals(-4,ai.get()); + while(!ai.weakCompareAndSet(-4,7)); + assertEquals(7,ai.get()); + } + + /** + * getAndSet returns previous value and sets to given value + */ + public void testGetAndSet(){ + AtomicInteger ai = new AtomicInteger(1); + assertEquals(1,ai.getAndSet(0)); + assertEquals(0,ai.getAndSet(-10)); + assertEquals(-10,ai.getAndSet(1)); + } + + /** + * getAndAdd returns previous value and adds given value + */ + public void testGetAndAdd(){ + AtomicInteger ai = new AtomicInteger(1); + assertEquals(1,ai.getAndAdd(2)); + assertEquals(3,ai.get()); + assertEquals(3,ai.getAndAdd(-4)); + assertEquals(-1,ai.get()); + } + + /** + * getAndDecrement returns previous value and decrements + */ + public void testGetAndDecrement(){ + AtomicInteger ai = new AtomicInteger(1); + assertEquals(1,ai.getAndDecrement()); + assertEquals(0,ai.getAndDecrement()); + assertEquals(-1,ai.getAndDecrement()); + } + + /** + * getAndIncrement returns previous value and increments + */ + public void testGetAndIncrement(){ + AtomicInteger ai = new AtomicInteger(1); + assertEquals(1,ai.getAndIncrement()); + assertEquals(2,ai.get()); + ai.set(-2); + assertEquals(-2,ai.getAndIncrement()); + assertEquals(-1,ai.getAndIncrement()); + assertEquals(0,ai.getAndIncrement()); + assertEquals(1,ai.get()); + } + + /** + * addAndGet adds given value to current, and returns current value + */ + public void testAddAndGet(){ + AtomicInteger ai = new AtomicInteger(1); + assertEquals(3,ai.addAndGet(2)); + assertEquals(3,ai.get()); + assertEquals(-1,ai.addAndGet(-4)); + assertEquals(-1,ai.get()); + } + + /** + * decrementAndGet decrements and returns current value + */ + public void testDecrementAndGet(){ + AtomicInteger ai = new AtomicInteger(1); + assertEquals(0,ai.decrementAndGet()); + assertEquals(-1,ai.decrementAndGet()); + assertEquals(-2,ai.decrementAndGet()); + assertEquals(-2,ai.get()); + } + + /** + * incrementAndGet increments and returns current value + */ + public void testIncrementAndGet(){ + AtomicInteger ai = new AtomicInteger(1); + assertEquals(2,ai.incrementAndGet()); + assertEquals(2,ai.get()); + ai.set(-2); + assertEquals(-1,ai.incrementAndGet()); + assertEquals(0,ai.incrementAndGet()); + assertEquals(1,ai.incrementAndGet()); + assertEquals(1,ai.get()); + } + + /** + * a deserialized serialized atomic holds same value + */ + public void testSerialization() { + AtomicInteger l = new AtomicInteger(); + + try { + l.set(22); + ByteArrayOutputStream bout = new ByteArrayOutputStream(10000); + ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout)); + out.writeObject(l); + out.close(); + + ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); + ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin)); + AtomicInteger r = (AtomicInteger) in.readObject(); + assertEquals(l.get(), r.get()); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * toString returns current value. + */ + public void testToString() { + AtomicInteger ai = new AtomicInteger(); + for (int i = -12; i < 6; ++i) { + ai.set(i); + assertEquals(ai.toString(), Integer.toString(i)); + } + } + + /** + * intValue returns current value. + */ + public void testIntValue() { + AtomicInteger ai = new AtomicInteger(); + for (int i = -12; i < 6; ++i) { + ai.set(i); + assertEquals(i, ai.intValue()); + } + } + + + /** + * longValue returns current value. + */ + public void testLongValue() { + AtomicInteger ai = new AtomicInteger(); + for (int i = -12; i < 6; ++i) { + ai.set(i); + assertEquals((long)i, ai.longValue()); + } + } + + /** + * floatValue returns current value. + */ + public void testFloatValue() { + AtomicInteger ai = new AtomicInteger(); + for (int i = -12; i < 6; ++i) { + ai.set(i); + assertEquals((float)i, ai.floatValue()); + } + } + + /** + * doubleValue returns current value. + */ + public void testDoubleValue() { + AtomicInteger ai = new AtomicInteger(); + for (int i = -12; i < 6; ++i) { + ai.set(i); + assertEquals((double)i, ai.doubleValue()); + } + } + + + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongArrayTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongArrayTest.java new file mode 100644 index 0000000..99ce204 --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongArrayTest.java @@ -0,0 +1,336 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.concurrent.atomic.*; +import java.io.*; +import java.util.*; + +public class AtomicLongArrayTest extends JSR166TestCase { + public static void main (String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(AtomicLongArrayTest.class); + } + + /** + * constructor creates array of given size with all elements zero + */ + public void testConstructor(){ + AtomicLongArray ai = new AtomicLongArray(SIZE); + for (int i = 0; i < SIZE; ++i) + assertEquals(0,ai.get(i)); + } + + /** + * constructor with null array throws NPE + */ + public void testConstructor2NPE() { + try { + long[] a = null; + AtomicLongArray ai = new AtomicLongArray(a); + } catch (NullPointerException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + /** + * constructor with array is of same size and has all elements + */ + public void testConstructor2() { + long[] a = { 17L, 3L, -42L, 99L, -7L}; + AtomicLongArray ai = new AtomicLongArray(a); + assertEquals(a.length, ai.length()); + for (int i = 0; i < a.length; ++i) + assertEquals(a[i], ai.get(i)); + } + + /** + * get and set for out of bound indices throw IndexOutOfBoundsException + */ + public void testIndexing(){ + AtomicLongArray ai = new AtomicLongArray(SIZE); + try { + ai.get(SIZE); + } catch(IndexOutOfBoundsException success){ + } + try { + ai.get(-1); + } catch(IndexOutOfBoundsException success){ + } + try { + ai.set(SIZE, 0); + } catch(IndexOutOfBoundsException success){ + } + try { + ai.set(-1, 0); + } catch(IndexOutOfBoundsException success){ + } + } + + /** + * get returns the last value set at index + */ + public void testGetSet(){ + AtomicLongArray ai = new AtomicLongArray(SIZE); + for (int i = 0; i < SIZE; ++i) { + ai.set(i, 1); + assertEquals(1,ai.get(i)); + ai.set(i, 2); + assertEquals(2,ai.get(i)); + ai.set(i, -3); + assertEquals(-3,ai.get(i)); + } + } + + /** + * compareAndSet succeeds in changing value if equal to expected else fails + */ + public void testCompareAndSet(){ + AtomicLongArray ai = new AtomicLongArray(SIZE); + for (int i = 0; i < SIZE; ++i) { + ai.set(i, 1); + assertTrue(ai.compareAndSet(i, 1,2)); + assertTrue(ai.compareAndSet(i, 2,-4)); + assertEquals(-4,ai.get(i)); + assertFalse(ai.compareAndSet(i, -5,7)); + assertFalse((7 == ai.get(i))); + assertTrue(ai.compareAndSet(i, -4,7)); + assertEquals(7,ai.get(i)); + } + } + + /** + * compareAndSet in one thread enables another waiting for value + * to succeed + */ + public void testCompareAndSetInMultipleThreads() { + final AtomicLongArray a = new AtomicLongArray(1); + a.set(0, 1); + Thread t = new Thread(new Runnable() { + public void run() { + while(!a.compareAndSet(0, 2, 3)) Thread.yield(); + }}); + try { + t.start(); + assertTrue(a.compareAndSet(0, 1, 2)); + t.join(LONG_DELAY_MS); + assertFalse(t.isAlive()); + assertEquals(a.get(0), 3); + } + catch(Exception e) { + unexpectedException(); + } + } + + /** + * repeated weakCompareAndSet succeeds in changing value when equal + * to expected + */ + public void testWeakCompareAndSet(){ + AtomicLongArray ai = new AtomicLongArray(SIZE); + for (int i = 0; i < SIZE; ++i) { + ai.set(i, 1); + while(!ai.weakCompareAndSet(i, 1,2)); + while(!ai.weakCompareAndSet(i, 2,-4)); + assertEquals(-4,ai.get(i)); + while(!ai.weakCompareAndSet(i, -4,7)); + assertEquals(7,ai.get(i)); + } + } + + /** + * getAndSet returns previous value and sets to given value at given index + */ + public void testGetAndSet(){ + AtomicLongArray ai = new AtomicLongArray(SIZE); + for (int i = 0; i < SIZE; ++i) { + ai.set(i, 1); + assertEquals(1,ai.getAndSet(i,0)); + assertEquals(0,ai.getAndSet(i,-10)); + assertEquals(-10,ai.getAndSet(i,1)); + } + } + + /** + * getAndAdd returns previous value and adds given value + */ + public void testGetAndAdd(){ + AtomicLongArray ai = new AtomicLongArray(SIZE); + for (int i = 0; i < SIZE; ++i) { + ai.set(i, 1); + assertEquals(1,ai.getAndAdd(i,2)); + assertEquals(3,ai.get(i)); + assertEquals(3,ai.getAndAdd(i,-4)); + assertEquals(-1,ai.get(i)); + } + } + + /** + * getAndDecrement returns previous value and decrements + */ + public void testGetAndDecrement(){ + AtomicLongArray ai = new AtomicLongArray(SIZE); + for (int i = 0; i < SIZE; ++i) { + ai.set(i, 1); + assertEquals(1,ai.getAndDecrement(i)); + assertEquals(0,ai.getAndDecrement(i)); + assertEquals(-1,ai.getAndDecrement(i)); + } + } + + /** + * getAndIncrement returns previous value and increments + */ + public void testGetAndIncrement(){ + AtomicLongArray ai = new AtomicLongArray(SIZE); + for (int i = 0; i < SIZE; ++i) { + ai.set(i, 1); + assertEquals(1,ai.getAndIncrement(i)); + assertEquals(2,ai.get(i)); + ai.set(i,-2); + assertEquals(-2,ai.getAndIncrement(i)); + assertEquals(-1,ai.getAndIncrement(i)); + assertEquals(0,ai.getAndIncrement(i)); + assertEquals(1,ai.get(i)); + } + } + + /** + * addAndGet adds given value to current, and returns current value + */ + public void testAddAndGet() { + AtomicLongArray ai = new AtomicLongArray(SIZE); + for (int i = 0; i < SIZE; ++i) { + ai.set(i, 1); + assertEquals(3,ai.addAndGet(i,2)); + assertEquals(3,ai.get(i)); + assertEquals(-1,ai.addAndGet(i,-4)); + assertEquals(-1,ai.get(i)); + } + } + + /** + * decrementAndGet decrements and returns current value + */ + public void testDecrementAndGet(){ + AtomicLongArray ai = new AtomicLongArray(SIZE); + for (int i = 0; i < SIZE; ++i) { + ai.set(i, 1); + assertEquals(0,ai.decrementAndGet(i)); + assertEquals(-1,ai.decrementAndGet(i)); + assertEquals(-2,ai.decrementAndGet(i)); + assertEquals(-2,ai.get(i)); + } + } + + /** + * incrementAndGet increments and returns current value + */ + public void testIncrementAndGet() { + AtomicLongArray ai = new AtomicLongArray(SIZE); + for (int i = 0; i < SIZE; ++i) { + ai.set(i, 1); + assertEquals(2,ai.incrementAndGet(i)); + assertEquals(2,ai.get(i)); + ai.set(i, -2); + assertEquals(-1,ai.incrementAndGet(i)); + assertEquals(0,ai.incrementAndGet(i)); + assertEquals(1,ai.incrementAndGet(i)); + assertEquals(1,ai.get(i)); + } + } + + static final long COUNTDOWN = 100000; + + class Counter implements Runnable { + final AtomicLongArray ai; + volatile long counts; + Counter(AtomicLongArray a) { ai = a; } + public void run() { + for (;;) { + boolean done = true; + for (int i = 0; i < ai.length(); ++i) { + long v = ai.get(i); + threadAssertTrue(v >= 0); + if (v != 0) { + done = false; + if (ai.compareAndSet(i, v, v-1)) + ++counts; + } + } + if (done) + break; + } + } + } + + /** + * Multiple threads using same array of counters successfully + * update a number of times equal to total count + */ + public void testCountingInMultipleThreads() { + try { + final AtomicLongArray ai = new AtomicLongArray(SIZE); + for (int i = 0; i < SIZE; ++i) + ai.set(i, COUNTDOWN); + Counter c1 = new Counter(ai); + Counter c2 = new Counter(ai); + Thread t1 = new Thread(c1); + Thread t2 = new Thread(c2); + t1.start(); + t2.start(); + t1.join(); + t2.join(); + assertEquals(c1.counts+c2.counts, SIZE * COUNTDOWN); + } + catch(InterruptedException ie) { + unexpectedException(); + } + } + + /** + * a deserialized serialized array holds same values + */ + public void testSerialization() { + AtomicLongArray l = new AtomicLongArray(SIZE); + for (int i = 0; i < SIZE; ++i) + l.set(i, -i); + + try { + ByteArrayOutputStream bout = new ByteArrayOutputStream(10000); + ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout)); + out.writeObject(l); + out.close(); + + ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); + ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin)); + AtomicLongArray r = (AtomicLongArray) in.readObject(); + for (int i = 0; i < SIZE; ++i) { + assertEquals(l.get(i), r.get(i)); + } + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * toString returns current value. + */ + public void testToString() { + long[] a = { 17, 3, -42, 99, -7}; + AtomicLongArray ai = new AtomicLongArray(a); + assertEquals(Arrays.toString(a), ai.toString()); + } + + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongFieldUpdaterTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongFieldUpdaterTest.java new file mode 100755 index 0000000..8076f7b --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongFieldUpdaterTest.java @@ -0,0 +1,277 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import java.util.concurrent.atomic.*; +import junit.framework.*; +import java.util.*; + +public class AtomicLongFieldUpdaterTest extends JSR166TestCase { + volatile long x = 0; + int z; + long w; + + public static void main(String[] args){ + junit.textui.TestRunner.run(suite()); + } + public static Test suite() { + return new TestSuite(AtomicLongFieldUpdaterTest.class); + } + + /** + * Construction with non-existent field throws RuntimeException + */ + public void testConstructor(){ + try{ + AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> + a = AtomicLongFieldUpdater.newUpdater + (AtomicLongFieldUpdaterTest.class, "y"); + shouldThrow(); + } + catch (RuntimeException rt) {} + } + + /** + * construction with field not of given type throws RuntimeException + */ + public void testConstructor2(){ + try{ + AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> + a = AtomicLongFieldUpdater.newUpdater + (AtomicLongFieldUpdaterTest.class, "z"); + shouldThrow(); + } + catch (RuntimeException rt) {} + } + + /** + * construction with non-volatile field throws RuntimeException + */ + public void testConstructor3(){ + try{ + AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> + a = AtomicLongFieldUpdater.newUpdater + (AtomicLongFieldUpdaterTest.class, "w"); + shouldThrow(); + } + + catch (RuntimeException rt) {} + } + + /** + * get returns the last value set or assigned + */ + public void testGetSet(){ + AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a; + try { + a = AtomicLongFieldUpdater.newUpdater(AtomicLongFieldUpdaterTest.class, "x"); + } catch (RuntimeException ok) { + return; + } + x = 1; + assertEquals(1,a.get(this)); + a.set(this,2); + assertEquals(2,a.get(this)); + a.set(this,-3); + assertEquals(-3,a.get(this)); + + } + /** + * compareAndSet succeeds in changing value if equal to expected else fails + */ + public void testCompareAndSet(){ + AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a; + try { + a = AtomicLongFieldUpdater.newUpdater(AtomicLongFieldUpdaterTest.class, "x"); + } catch (RuntimeException ok) { + return; + } + x = 1; + assertTrue(a.compareAndSet(this,1,2)); + assertTrue(a.compareAndSet(this,2,-4)); + assertEquals(-4,a.get(this)); + assertFalse(a.compareAndSet(this,-5,7)); + assertFalse((7 == a.get(this))); + assertTrue(a.compareAndSet(this,-4,7)); + assertEquals(7,a.get(this)); + } + + + /** + * compareAndSet in one thread enables another waiting for value + * to succeed + */ + public void testCompareAndSetInMultipleThreads() { + x = 1; + final AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest>a; + try { + a = AtomicLongFieldUpdater.newUpdater(AtomicLongFieldUpdaterTest.class, "x"); + } catch (RuntimeException ok) { + return; + } + + Thread t = new Thread(new Runnable() { + public void run() { + while(!a.compareAndSet(AtomicLongFieldUpdaterTest.this, 2, 3)) Thread.yield(); + }}); + try { + t.start(); + assertTrue(a.compareAndSet(this, 1, 2)); + t.join(LONG_DELAY_MS); + assertFalse(t.isAlive()); + assertEquals(a.get(this), 3); + } + catch(Exception e) { + unexpectedException(); + } + } + + /** + * repeated weakCompareAndSet succeeds in changing value when equal + * to expected + */ + public void testWeakCompareAndSet(){ + AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a; + try { + a = AtomicLongFieldUpdater.newUpdater(AtomicLongFieldUpdaterTest.class, "x"); + } catch (RuntimeException ok) { + return; + } + x = 1; + while(!a.weakCompareAndSet(this,1,2)); + while(!a.weakCompareAndSet(this,2,-4)); + assertEquals(-4,a.get(this)); + while(!a.weakCompareAndSet(this,-4,7)); + assertEquals(7,a.get(this)); + } + + /** + * getAndSet returns previous value and sets to given value + */ + public void testGetAndSet(){ + AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a; + try { + a = AtomicLongFieldUpdater.newUpdater(AtomicLongFieldUpdaterTest.class, "x"); + } catch (RuntimeException ok) { + return; + } + x = 1; + assertEquals(1,a.getAndSet(this, 0)); + assertEquals(0,a.getAndSet(this,-10)); + assertEquals(-10,a.getAndSet(this,1)); + } + + /** + * getAndAdd returns previous value and adds given value + */ + public void testGetAndAdd(){ + AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a; + try { + a = AtomicLongFieldUpdater.newUpdater(AtomicLongFieldUpdaterTest.class, "x"); + } catch (RuntimeException ok) { + return; + } + x = 1; + assertEquals(1,a.getAndAdd(this,2)); + assertEquals(3,a.get(this)); + assertEquals(3,a.getAndAdd(this,-4)); + assertEquals(-1,a.get(this)); + } + + /** + * getAndDecrement returns previous value and decrements + */ + public void testGetAndDecrement(){ + AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a; + try { + a = AtomicLongFieldUpdater.newUpdater(AtomicLongFieldUpdaterTest.class, "x"); + } catch (RuntimeException ok) { + return; + } + x = 1; + assertEquals(1,a.getAndDecrement(this)); + assertEquals(0,a.getAndDecrement(this)); + assertEquals(-1,a.getAndDecrement(this)); + } + + /** + * getAndIncrement returns previous value and increments + */ + public void testGetAndIncrement(){ + AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a; + try { + a = AtomicLongFieldUpdater.newUpdater(AtomicLongFieldUpdaterTest.class, "x"); + } catch (RuntimeException ok) { + return; + } + x = 1; + assertEquals(1,a.getAndIncrement(this)); + assertEquals(2,a.get(this)); + a.set(this,-2); + assertEquals(-2,a.getAndIncrement(this)); + assertEquals(-1,a.getAndIncrement(this)); + assertEquals(0,a.getAndIncrement(this)); + assertEquals(1,a.get(this)); + } + + /** + * addAndGet adds given value to current, and returns current value + */ + public void testAddAndGet(){ + AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a; + try { + a = AtomicLongFieldUpdater.newUpdater(AtomicLongFieldUpdaterTest.class, "x"); + } catch (RuntimeException ok) { + return; + } + x = 1; + assertEquals(3,a.addAndGet(this,2)); + assertEquals(3,a.get(this)); + assertEquals(-1,a.addAndGet(this,-4)); + assertEquals(-1,a.get(this)); + } + + /** + * decrementAndGet decrements and returns current value + */ + public void testDecrementAndGet(){ + AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a; + try { + a = AtomicLongFieldUpdater.newUpdater(AtomicLongFieldUpdaterTest.class, "x"); + } catch (RuntimeException ok) { + return; + } + x = 1; + assertEquals(0,a.decrementAndGet(this)); + assertEquals(-1,a.decrementAndGet(this)); + assertEquals(-2,a.decrementAndGet(this)); + assertEquals(-2,a.get(this)); + } + + /** + * incrementAndGet increments and returns current value + */ + public void testIncrementAndGet(){ + AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a; + try { + a = AtomicLongFieldUpdater.newUpdater(AtomicLongFieldUpdaterTest.class, "x"); + } catch (RuntimeException ok) { + return; + } + x = 1; + assertEquals(2,a.incrementAndGet(this)); + assertEquals(2,a.get(this)); + a.set(this,-2); + assertEquals(-1,a.incrementAndGet(this)); + assertEquals(0,a.incrementAndGet(this)); + assertEquals(1,a.incrementAndGet(this)); + assertEquals(1,a.get(this)); + } + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongTest.java new file mode 100755 index 0000000..55b8a49 --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongTest.java @@ -0,0 +1,248 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.concurrent.atomic.*; +import java.io.*; + +public class AtomicLongTest extends JSR166TestCase { + public static void main (String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(AtomicLongTest.class); + } + + /** + * constructor initializes to given value + */ + public void testConstructor(){ + AtomicLong ai = new AtomicLong(1); + assertEquals(1,ai.get()); + } + + /** + * default constructed initializes to zero + */ + public void testConstructor2(){ + AtomicLong ai = new AtomicLong(); + assertEquals(0,ai.get()); + } + + /** + * get returns the last value set + */ + public void testGetSet(){ + AtomicLong ai = new AtomicLong(1); + assertEquals(1,ai.get()); + ai.set(2); + assertEquals(2,ai.get()); + ai.set(-3); + assertEquals(-3,ai.get()); + + } + /** + * compareAndSet succeeds in changing value if equal to expected else fails + */ + public void testCompareAndSet(){ + AtomicLong ai = new AtomicLong(1); + assertTrue(ai.compareAndSet(1,2)); + assertTrue(ai.compareAndSet(2,-4)); + assertEquals(-4,ai.get()); + assertFalse(ai.compareAndSet(-5,7)); + assertFalse((7 == ai.get())); + assertTrue(ai.compareAndSet(-4,7)); + assertEquals(7,ai.get()); + } + + /** + * compareAndSet in one thread enables another waiting for value + * to succeed + */ + public void testCompareAndSetInMultipleThreads() { + final AtomicLong ai = new AtomicLong(1); + Thread t = new Thread(new Runnable() { + public void run() { + while(!ai.compareAndSet(2, 3)) Thread.yield(); + }}); + try { + t.start(); + assertTrue(ai.compareAndSet(1, 2)); + t.join(LONG_DELAY_MS); + assertFalse(t.isAlive()); + assertEquals(ai.get(), 3); + } + catch(Exception e) { + unexpectedException(); + } + } + + /** + * repeated weakCompareAndSet succeeds in changing value when equal + * to expected + */ + public void testWeakCompareAndSet(){ + AtomicLong ai = new AtomicLong(1); + while(!ai.weakCompareAndSet(1,2)); + while(!ai.weakCompareAndSet(2,-4)); + assertEquals(-4,ai.get()); + while(!ai.weakCompareAndSet(-4,7)); + assertEquals(7,ai.get()); + } + + /** + * getAndSet returns previous value and sets to given value + */ + public void testGetAndSet(){ + AtomicLong ai = new AtomicLong(1); + assertEquals(1,ai.getAndSet(0)); + assertEquals(0,ai.getAndSet(-10)); + assertEquals(-10,ai.getAndSet(1)); + } + + /** + * getAndAdd returns previous value and adds given value + */ + public void testGetAndAdd(){ + AtomicLong ai = new AtomicLong(1); + assertEquals(1,ai.getAndAdd(2)); + assertEquals(3,ai.get()); + assertEquals(3,ai.getAndAdd(-4)); + assertEquals(-1,ai.get()); + } + + /** + * getAndDecrement returns previous value and decrements + */ + public void testGetAndDecrement(){ + AtomicLong ai = new AtomicLong(1); + assertEquals(1,ai.getAndDecrement()); + assertEquals(0,ai.getAndDecrement()); + assertEquals(-1,ai.getAndDecrement()); + } + + /** + * getAndIncrement returns previous value and increments + */ + public void testGetAndIncrement(){ + AtomicLong ai = new AtomicLong(1); + assertEquals(1,ai.getAndIncrement()); + assertEquals(2,ai.get()); + ai.set(-2); + assertEquals(-2,ai.getAndIncrement()); + assertEquals(-1,ai.getAndIncrement()); + assertEquals(0,ai.getAndIncrement()); + assertEquals(1,ai.get()); + } + + /** + * addAndGet adds given value to current, and returns current value + */ + public void testAddAndGet(){ + AtomicLong ai = new AtomicLong(1); + assertEquals(3,ai.addAndGet(2)); + assertEquals(3,ai.get()); + assertEquals(-1,ai.addAndGet(-4)); + assertEquals(-1,ai.get()); + } + + /** + * decrementAndGet decrements and returns current value + */ + public void testDecrementAndGet(){ + AtomicLong ai = new AtomicLong(1); + assertEquals(0,ai.decrementAndGet()); + assertEquals(-1,ai.decrementAndGet()); + assertEquals(-2,ai.decrementAndGet()); + assertEquals(-2,ai.get()); + } + + /** + * incrementAndGet increments and returns current value + */ + public void testIncrementAndGet(){ + AtomicLong ai = new AtomicLong(1); + assertEquals(2,ai.incrementAndGet()); + assertEquals(2,ai.get()); + ai.set(-2); + assertEquals(-1,ai.incrementAndGet()); + assertEquals(0,ai.incrementAndGet()); + assertEquals(1,ai.incrementAndGet()); + assertEquals(1,ai.get()); + } + + /** + * a deserialized serialized atomic holds same value + */ + public void testSerialization() { + AtomicLong l = new AtomicLong(); + + try { + l.set(-22); + ByteArrayOutputStream bout = new ByteArrayOutputStream(10000); + ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout)); + out.writeObject(l); + out.close(); + + ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); + ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin)); + AtomicLong r = (AtomicLong) in.readObject(); + assertEquals(l.get(), r.get()); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * toString returns current value. + */ + public void testToString() { + AtomicLong ai = new AtomicLong(); + for (long i = -12; i < 6; ++i) { + ai.set(i); + assertEquals(ai.toString(), Long.toString(i)); + } + } + + /** + * longValue returns current value. + */ + public void testLongValue() { + AtomicLong ai = new AtomicLong(); + for (int i = -12; i < 6; ++i) { + ai.set(i); + assertEquals((long)i, ai.longValue()); + } + } + + /** + * floatValue returns current value. + */ + public void testFloatValue() { + AtomicLong ai = new AtomicLong(); + for (int i = -12; i < 6; ++i) { + ai.set(i); + assertEquals((float)i, ai.floatValue()); + } + } + + /** + * doubleValue returns current value. + */ + public void testDoubleValue() { + AtomicLong ai = new AtomicLong(); + for (int i = -12; i < 6; ++i) { + ai.set(i); + assertEquals((double)i, ai.doubleValue()); + } + } + + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicMarkableReferenceTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicMarkableReferenceTest.java new file mode 100755 index 0000000..7b3dcb1 --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicMarkableReferenceTest.java @@ -0,0 +1,160 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.concurrent.atomic.*; + +public class AtomicMarkableReferenceTest extends JSR166TestCase{ + public static void main (String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(AtomicMarkableReferenceTest.class); + } + + /** + * constructor initializes to given reference and mark + */ + public void testConstructor(){ + AtomicMarkableReference ai = new AtomicMarkableReference(one, false); + assertEquals(one,ai.getReference()); + assertFalse(ai.isMarked()); + AtomicMarkableReference a2 = new AtomicMarkableReference(null, true); + assertNull(a2.getReference()); + assertTrue(a2.isMarked()); + + } + + /** + * get returns the last values of reference and mark set + */ + public void testGetSet(){ + boolean[] mark = new boolean[1]; + AtomicMarkableReference ai = new AtomicMarkableReference(one, false); + assertEquals(one,ai.getReference()); + assertFalse(ai.isMarked()); + assertEquals(one, ai.get(mark)); + assertFalse(mark[0]); + ai.set(two, false); + assertEquals(two,ai.getReference()); + assertFalse(ai.isMarked()); + assertEquals(two, ai.get(mark)); + assertFalse(mark[0]); + ai.set(one, true); + assertEquals(one,ai.getReference()); + assertTrue(ai.isMarked()); + assertEquals(one, ai.get(mark)); + assertTrue(mark[0]); + } + + /** + * attemptMark succeeds in single thread + */ + public void testAttemptMark(){ + boolean[] mark = new boolean[1]; + AtomicMarkableReference ai = new AtomicMarkableReference(one, false); + assertFalse(ai.isMarked()); + assertTrue(ai.attemptMark(one, true)); + assertTrue(ai.isMarked()); + assertEquals(one, ai.get(mark)); + assertTrue(mark[0]); + } + + /** + * compareAndSet succeeds in changing values if equal to expected reference + * and mark else fails + */ + public void testCompareAndSet(){ + boolean[] mark = new boolean[1]; + AtomicMarkableReference ai = new AtomicMarkableReference(one, false); + assertEquals(one, ai.get(mark)); + assertFalse(ai.isMarked()); + assertFalse(mark[0]); + + assertTrue(ai.compareAndSet(one, two, false, false)); + assertEquals(two, ai.get(mark)); + assertFalse(mark[0]); + + assertTrue(ai.compareAndSet(two, m3, false, true)); + assertEquals(m3, ai.get(mark)); + assertTrue(mark[0]); + + assertFalse(ai.compareAndSet(two, m3, true, true)); + assertEquals(m3, ai.get(mark)); + assertTrue(mark[0]); + } + + /** + * compareAndSet in one thread enables another waiting for reference value + * to succeed + */ + public void testCompareAndSetInMultipleThreads() { + final AtomicMarkableReference ai = new AtomicMarkableReference(one, false); + Thread t = new Thread(new Runnable() { + public void run() { + while(!ai.compareAndSet(two, three, false, false)) Thread.yield(); + }}); + try { + t.start(); + assertTrue(ai.compareAndSet(one, two, false, false)); + t.join(LONG_DELAY_MS); + assertFalse(t.isAlive()); + assertEquals(ai.getReference(), three); + assertFalse(ai.isMarked()); + } + catch(Exception e) { + unexpectedException(); + } + } + + /** + * compareAndSet in one thread enables another waiting for mark value + * to succeed + */ + public void testCompareAndSetInMultipleThreads2() { + final AtomicMarkableReference ai = new AtomicMarkableReference(one, false); + Thread t = new Thread(new Runnable() { + public void run() { + while(!ai.compareAndSet(one, one, true, false)) Thread.yield(); + }}); + try { + t.start(); + assertTrue(ai.compareAndSet(one, one, false, true)); + t.join(LONG_DELAY_MS); + assertFalse(t.isAlive()); + assertEquals(ai.getReference(), one); + assertFalse(ai.isMarked()); + } + catch(Exception e) { + unexpectedException(); + } + } + + /** + * repeated weakCompareAndSet succeeds in changing values when equal + * to expected + */ + public void testWeakCompareAndSet(){ + boolean[] mark = new boolean[1]; + AtomicMarkableReference ai = new AtomicMarkableReference(one, false); + assertEquals(one, ai.get(mark)); + assertFalse(ai.isMarked()); + assertFalse(mark[0]); + + while(!ai.weakCompareAndSet(one, two, false, false)); + assertEquals(two, ai.get(mark)); + assertFalse(mark[0]); + + while(!ai.weakCompareAndSet(two, m3, false, true)); + assertEquals(m3, ai.get(mark)); + assertTrue(mark[0]); + } + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceArrayTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceArrayTest.java new file mode 100644 index 0000000..9330d39 --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceArrayTest.java @@ -0,0 +1,203 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.concurrent.atomic.*; +import java.io.*; +import java.util.*; + +public class AtomicReferenceArrayTest extends JSR166TestCase +{ + public static void main (String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(AtomicReferenceArrayTest.class); + } + + /** + * constructor creates array of given size with all elements null + */ + public void testConstructor(){ + AtomicReferenceArray<Integer> ai = new AtomicReferenceArray<Integer>(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertNull(ai.get(i)); + } + } + + /** + * constructor with null array throws NPE + */ + public void testConstructor2NPE() { + try { + Integer[] a = null; + AtomicReferenceArray<Integer> ai = new AtomicReferenceArray<Integer>(a); + } catch (NullPointerException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + /** + * constructor with array is of same size and has all elements + */ + public void testConstructor2() { + Integer[] a = { two, one, three, four, seven}; + AtomicReferenceArray<Integer> ai = new AtomicReferenceArray<Integer>(a); + assertEquals(a.length, ai.length()); + for (int i = 0; i < a.length; ++i) + assertEquals(a[i], ai.get(i)); + } + + + /** + * get and set for out of bound indices throw IndexOutOfBoundsException + */ + public void testIndexing(){ + AtomicReferenceArray<Integer> ai = new AtomicReferenceArray<Integer>(SIZE); + try { + ai.get(SIZE); + } catch(IndexOutOfBoundsException success){ + } + try { + ai.get(-1); + } catch(IndexOutOfBoundsException success){ + } + try { + ai.set(SIZE, null); + } catch(IndexOutOfBoundsException success){ + } + try { + ai.set(-1, null); + } catch(IndexOutOfBoundsException success){ + } + } + + /** + * get returns the last value set at index + */ + public void testGetSet(){ + AtomicReferenceArray ai = new AtomicReferenceArray(SIZE); + for (int i = 0; i < SIZE; ++i) { + ai.set(i, one); + assertEquals(one,ai.get(i)); + ai.set(i, two); + assertEquals(two,ai.get(i)); + ai.set(i, m3); + assertEquals(m3,ai.get(i)); + } + } + + /** + * compareAndSet succeeds in changing value if equal to expected else fails + */ + public void testCompareAndSet(){ + AtomicReferenceArray ai = new AtomicReferenceArray(SIZE); + for (int i = 0; i < SIZE; ++i) { + ai.set(i, one); + assertTrue(ai.compareAndSet(i, one,two)); + assertTrue(ai.compareAndSet(i, two,m4)); + assertEquals(m4,ai.get(i)); + assertFalse(ai.compareAndSet(i, m5,seven)); + assertFalse((seven.equals(ai.get(i)))); + assertTrue(ai.compareAndSet(i, m4,seven)); + assertEquals(seven,ai.get(i)); + } + } + + /** + * compareAndSet in one thread enables another waiting for value + * to succeed + */ + public void testCompareAndSetInMultipleThreads() { + final AtomicReferenceArray a = new AtomicReferenceArray(1); + a.set(0, one); + Thread t = new Thread(new Runnable() { + public void run() { + while(!a.compareAndSet(0, two, three)) Thread.yield(); + }}); + try { + t.start(); + assertTrue(a.compareAndSet(0, one, two)); + t.join(LONG_DELAY_MS); + assertFalse(t.isAlive()); + assertEquals(a.get(0), three); + } + catch(Exception e) { + unexpectedException(); + } + } + + /** + * repeated weakCompareAndSet succeeds in changing value when equal + * to expected + */ + public void testWeakCompareAndSet(){ + AtomicReferenceArray ai = new AtomicReferenceArray(SIZE); + for (int i = 0; i < SIZE; ++i) { + ai.set(i, one); + while(!ai.weakCompareAndSet(i, one,two)); + while(!ai.weakCompareAndSet(i, two,m4)); + assertEquals(m4,ai.get(i)); + while(!ai.weakCompareAndSet(i, m4,seven)); + assertEquals(seven,ai.get(i)); + } + } + + /** + * getAndSet returns previous value and sets to given value at given index + */ + public void testGetAndSet(){ + AtomicReferenceArray ai = new AtomicReferenceArray(SIZE); + for (int i = 0; i < SIZE; ++i) { + ai.set(i, one); + assertEquals(one,ai.getAndSet(i,zero)); + assertEquals(0,ai.getAndSet(i,m10)); + assertEquals(m10,ai.getAndSet(i,one)); + } + } + + /** + * a deserialized serialized array holds same values + */ + public void testSerialization() { + AtomicReferenceArray l = new AtomicReferenceArray(SIZE); + for (int i = 0; i < SIZE; ++i) { + l.set(i, new Integer(-i)); + } + + try { + ByteArrayOutputStream bout = new ByteArrayOutputStream(10000); + ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout)); + out.writeObject(l); + out.close(); + + ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); + ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin)); + AtomicReferenceArray r = (AtomicReferenceArray) in.readObject(); + assertEquals(l.length(), r.length()); + for (int i = 0; i < SIZE; ++i) { + assertEquals(r.get(i), l.get(i)); + } + } catch(Exception e){ + unexpectedException(); + } + } + + + /** + * toString returns current value. + */ + public void testToString() { + Integer[] a = { two, one, three, four, seven}; + AtomicReferenceArray<Integer> ai = new AtomicReferenceArray<Integer>(a); + assertEquals(Arrays.toString(a), ai.toString()); + } +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceFieldUpdaterTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceFieldUpdaterTest.java new file mode 100755 index 0000000..183ca21 --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceFieldUpdaterTest.java @@ -0,0 +1,171 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import java.util.concurrent.atomic.*; +import junit.framework.*; +import java.util.*; + +public class AtomicReferenceFieldUpdaterTest extends JSR166TestCase{ + volatile Integer x = null; + Object z; + Integer w; + + public static void main(String[] args){ + junit.textui.TestRunner.run(suite()); + } + public static Test suite() { + return new TestSuite(AtomicReferenceFieldUpdaterTest.class); + } + + /** + * Construction with non-existent field throws RuntimeException + */ + public void testConstructor(){ + try{ + AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> + a = AtomicReferenceFieldUpdater.newUpdater + (AtomicReferenceFieldUpdaterTest.class, Integer.class, "y"); + shouldThrow(); + } + catch (RuntimeException rt) {} + } + + + /** + * construction with field not of given type throws RuntimeException + */ + public void testConstructor2(){ + try{ + AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> + a = AtomicReferenceFieldUpdater.newUpdater + (AtomicReferenceFieldUpdaterTest.class, Integer.class, "z"); + shouldThrow(); + } + catch (RuntimeException rt) {} + } + + /** + * Constructor with non-volatile field throws exception + */ + public void testConstructor3(){ + try{ + AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> + a = AtomicReferenceFieldUpdater.newUpdater + (AtomicReferenceFieldUpdaterTest.class, Integer.class, "w"); + shouldThrow(); + } + catch (RuntimeException rt) {} + } + + /** + * get returns the last value set or assigned + */ + public void testGetSet(){ + AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer>a; + try { + a = AtomicReferenceFieldUpdater.newUpdater(AtomicReferenceFieldUpdaterTest.class, Integer.class, "x"); + } catch (RuntimeException ok) { + return; + } + x = one; + assertEquals(one,a.get(this)); + a.set(this,two); + assertEquals(two,a.get(this)); + a.set(this,-3); + // BEGIN android-changed + assertEquals(new Integer(-3),a.get(this)); + // END android-changed + + } + /** + * compareAndSet succeeds in changing value if equal to expected else fails + */ + public void testCompareAndSet(){ + AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer>a; + try { + a = AtomicReferenceFieldUpdater.newUpdater(AtomicReferenceFieldUpdaterTest.class, Integer.class, "x"); + } catch (RuntimeException ok) { + return; + } + x = one; + assertTrue(a.compareAndSet(this,one,two)); + assertTrue(a.compareAndSet(this,two,m4)); + assertEquals(m4,a.get(this)); + assertFalse(a.compareAndSet(this,m5,seven)); + assertFalse((seven == a.get(this))); + assertTrue(a.compareAndSet(this,m4,seven)); + assertEquals(seven,a.get(this)); + } + + /** + * compareAndSet in one thread enables another waiting for value + * to succeed + */ + public void testCompareAndSetInMultipleThreads() { + x = one; + final AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer>a; + try { + a = AtomicReferenceFieldUpdater.newUpdater(AtomicReferenceFieldUpdaterTest.class, Integer.class, "x"); + } catch (RuntimeException ok) { + return; + } + + Thread t = new Thread(new Runnable() { + public void run() { + while(!a.compareAndSet(AtomicReferenceFieldUpdaterTest.this, two, three)) Thread.yield(); + }}); + try { + t.start(); + assertTrue(a.compareAndSet(this, one, two)); + t.join(LONG_DELAY_MS); + assertFalse(t.isAlive()); + assertEquals(a.get(this), three); + } + catch(Exception e) { + unexpectedException(); + } + } + + /** + * repeated weakCompareAndSet succeeds in changing value when equal + * to expected + */ + public void testWeakCompareAndSet(){ + AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer>a; + try { + a = AtomicReferenceFieldUpdater.newUpdater(AtomicReferenceFieldUpdaterTest.class, Integer.class, "x"); + } catch (RuntimeException ok) { + return; + } + x = one; + while(!a.weakCompareAndSet(this,one,two)); + while(!a.weakCompareAndSet(this,two,m4)); + assertEquals(m4,a.get(this)); + while(!a.weakCompareAndSet(this,m4,seven)); + assertEquals(seven,a.get(this)); + } + + /** + * getAndSet returns previous value and sets to given value + */ + public void testGetAndSet(){ + AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer>a; + try { + a = AtomicReferenceFieldUpdater.newUpdater(AtomicReferenceFieldUpdaterTest.class, Integer.class, "x"); + } catch (RuntimeException ok) { + return; + } + x = one; + assertEquals(one,a.getAndSet(this, zero)); + assertEquals(zero,a.getAndSet(this,m10)); + assertEquals(m10,a.getAndSet(this,1)); + } + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceTest.java new file mode 100755 index 0000000..0aa48cd --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceTest.java @@ -0,0 +1,143 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.concurrent.atomic.*; +import java.io.*; + +public class AtomicReferenceTest extends JSR166TestCase { + public static void main (String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(AtomicReferenceTest.class); + } + + /** + * constructor initializes to given value + */ + public void testConstructor(){ + AtomicReference ai = new AtomicReference(one); + assertEquals(one,ai.get()); + } + + /** + * default constructed initializes to null + */ + public void testConstructor2(){ + AtomicReference ai = new AtomicReference(); + assertNull(ai.get()); + } + + /** + * get returns the last value set + */ + public void testGetSet(){ + AtomicReference ai = new AtomicReference(one); + assertEquals(one,ai.get()); + ai.set(two); + assertEquals(two,ai.get()); + ai.set(m3); + assertEquals(m3,ai.get()); + + } + /** + * compareAndSet succeeds in changing value if equal to expected else fails + */ + public void testCompareAndSet(){ + AtomicReference ai = new AtomicReference(one); + assertTrue(ai.compareAndSet(one,two)); + assertTrue(ai.compareAndSet(two,m4)); + assertEquals(m4,ai.get()); + assertFalse(ai.compareAndSet(m5,seven)); + assertFalse((seven.equals(ai.get()))); + assertTrue(ai.compareAndSet(m4,seven)); + assertEquals(seven,ai.get()); + } + + /** + * compareAndSet in one thread enables another waiting for value + * to succeed + */ + public void testCompareAndSetInMultipleThreads() { + final AtomicReference ai = new AtomicReference(one); + Thread t = new Thread(new Runnable() { + public void run() { + while(!ai.compareAndSet(two, three)) Thread.yield(); + }}); + try { + t.start(); + assertTrue(ai.compareAndSet(one, two)); + t.join(LONG_DELAY_MS); + assertFalse(t.isAlive()); + assertEquals(ai.get(), three); + } + catch(Exception e) { + unexpectedException(); + } + } + + /** + * repeated weakCompareAndSet succeeds in changing value when equal + * to expected + */ + public void testWeakCompareAndSet(){ + AtomicReference ai = new AtomicReference(one); + while(!ai.weakCompareAndSet(one,two)); + while(!ai.weakCompareAndSet(two,m4)); + assertEquals(m4,ai.get()); + while(!ai.weakCompareAndSet(m4,seven)); + assertEquals(seven,ai.get()); + } + + /** + * getAndSet returns previous value and sets to given value + */ + public void testGetAndSet(){ + AtomicReference ai = new AtomicReference(one); + assertEquals(one,ai.getAndSet(zero)); + assertEquals(zero,ai.getAndSet(m10)); + assertEquals(m10,ai.getAndSet(one)); + } + + /** + * a deserialized serialized atomic holds same value + */ + public void testSerialization() { + AtomicReference l = new AtomicReference(); + + try { + l.set(one); + ByteArrayOutputStream bout = new ByteArrayOutputStream(10000); + ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout)); + out.writeObject(l); + out.close(); + + ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); + ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin)); + AtomicReference r = (AtomicReference) in.readObject(); + assertEquals(l.get(), r.get()); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * toString returns current value. + */ + public void testToString() { + AtomicReference<Integer> ai = new AtomicReference<Integer>(one); + assertEquals(ai.toString(), one.toString()); + ai.set(two); + assertEquals(ai.toString(), two.toString()); + } + +} + diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicStampedReferenceTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicStampedReferenceTest.java new file mode 100755 index 0000000..3ffc0a7 --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicStampedReferenceTest.java @@ -0,0 +1,160 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.concurrent.atomic.*; + +public class AtomicStampedReferenceTest extends JSR166TestCase{ + public static void main (String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(AtomicStampedReferenceTest.class); + } + + /** + * constructor initializes to given reference and stamp + */ + public void testConstructor(){ + AtomicStampedReference ai = new AtomicStampedReference(one, 0); + assertEquals(one,ai.getReference()); + assertEquals(0, ai.getStamp()); + AtomicStampedReference a2 = new AtomicStampedReference(null, 1); + assertNull(a2.getReference()); + assertEquals(1, a2.getStamp()); + + } + + /** + * get returns the last values of reference and stamp set + */ + public void testGetSet(){ + int[] mark = new int[1]; + AtomicStampedReference ai = new AtomicStampedReference(one, 0); + assertEquals(one,ai.getReference()); + assertEquals(0, ai.getStamp()); + assertEquals(one, ai.get(mark)); + assertEquals(0, mark[0]); + ai.set(two, 0); + assertEquals(two,ai.getReference()); + assertEquals(0, ai.getStamp()); + assertEquals(two, ai.get(mark)); + assertEquals(0, mark[0]); + ai.set(one, 1); + assertEquals(one,ai.getReference()); + assertEquals(1, ai.getStamp()); + assertEquals(one, ai.get(mark)); + assertEquals(1,mark[0]); + } + + /** + * attemptStamp succeeds in single thread + */ + public void testAttemptStamp(){ + int[] mark = new int[1]; + AtomicStampedReference ai = new AtomicStampedReference(one, 0); + assertEquals(0, ai.getStamp()); + assertTrue(ai.attemptStamp(one, 1)); + assertEquals(1, ai.getStamp()); + assertEquals(one, ai.get(mark)); + assertEquals(1, mark[0]); + } + + /** + * compareAndSet succeeds in changing values if equal to expected reference + * and stamp else fails + */ + public void testCompareAndSet(){ + int[] mark = new int[1]; + AtomicStampedReference ai = new AtomicStampedReference(one, 0); + assertEquals(one, ai.get(mark)); + assertEquals(0, ai.getStamp()); + assertEquals(0, mark[0]); + + assertTrue(ai.compareAndSet(one, two, 0, 0)); + assertEquals(two, ai.get(mark)); + assertEquals(0, mark[0]); + + assertTrue(ai.compareAndSet(two, m3, 0, 1)); + assertEquals(m3, ai.get(mark)); + assertEquals(1, mark[0]); + + assertFalse(ai.compareAndSet(two, m3, 1, 1)); + assertEquals(m3, ai.get(mark)); + assertEquals(1, mark[0]); + } + + /** + * compareAndSet in one thread enables another waiting for reference value + * to succeed + */ + public void testCompareAndSetInMultipleThreads() { + final AtomicStampedReference ai = new AtomicStampedReference(one, 0); + Thread t = new Thread(new Runnable() { + public void run() { + while(!ai.compareAndSet(two, three, 0, 0)) Thread.yield(); + }}); + try { + t.start(); + assertTrue(ai.compareAndSet(one, two, 0, 0)); + t.join(LONG_DELAY_MS); + assertFalse(t.isAlive()); + assertEquals(ai.getReference(), three); + assertEquals(ai.getStamp(), 0); + } + catch(Exception e) { + unexpectedException(); + } + } + + /** + * compareAndSet in one thread enables another waiting for stamp value + * to succeed + */ + public void testCompareAndSetInMultipleThreads2() { + final AtomicStampedReference ai = new AtomicStampedReference(one, 0); + Thread t = new Thread(new Runnable() { + public void run() { + while(!ai.compareAndSet(one, one, 1, 2)) Thread.yield(); + }}); + try { + t.start(); + assertTrue(ai.compareAndSet(one, one, 0, 1)); + t.join(LONG_DELAY_MS); + assertFalse(t.isAlive()); + assertEquals(ai.getReference(), one); + assertEquals(ai.getStamp(), 2); + } + catch(Exception e) { + unexpectedException(); + } + } + + /** + * repeated weakCompareAndSet succeeds in changing values when equal + * to expected + */ + public void testWeakCompareAndSet(){ + int[] mark = new int[1]; + AtomicStampedReference ai = new AtomicStampedReference(one, 0); + assertEquals(one, ai.get(mark)); + assertEquals(0, ai.getStamp ()); + assertEquals(0, mark[0]); + + while(!ai.weakCompareAndSet(one, two, 0, 0)); + assertEquals(two, ai.get(mark)); + assertEquals(0, mark[0]); + + while(!ai.weakCompareAndSet(two, m3, 0, 1)); + assertEquals(m3, ai.get(mark)); + assertEquals(1, mark[0]); + } + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentHashMapTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentHashMapTest.java new file mode 100755 index 0000000..9b3ec52 --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentHashMapTest.java @@ -0,0 +1,611 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.*; +import java.util.concurrent.*; +import java.util.Enumeration; +import java.io.*; + +public class ConcurrentHashMapTest extends JSR166TestCase{ + public static void main(String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(ConcurrentHashMapTest.class); + } + // BEGIN android-added + static class MyConcurrentHashMap<V, K> extends ConcurrentHashMap<K, V> + implements Cloneable { + + public MyConcurrentHashMap() { + super(); + } + + public MyConcurrentHashMap(int initialCapacity, float loadFactor, + int concurrencyLevel) { + super(initialCapacity, loadFactor, concurrencyLevel); + } + + public MyConcurrentHashMap(int initialCapacity) { + super(initialCapacity); + } + + public MyConcurrentHashMap(Map<? extends K, ? extends V> t) { + super(t); + } + + @Override + protected Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + } + + /** + * Create a map from Integers 1-5 to Strings "A"-"E". + */ + private static MyConcurrentHashMap myMap5() { + MyConcurrentHashMap map = new MyConcurrentHashMap(5); + assertTrue(map.isEmpty()); + map.put(one, "A"); + map.put(two, "B"); + map.put(three, "C"); + map.put(four, "D"); + map.put(five, "E"); + assertFalse(map.isEmpty()); + assertEquals(5, map.size()); + return map; + } + // END android-added + /** + * Create a map from Integers 1-5 to Strings "A"-"E". + */ + private static ConcurrentHashMap map5() { + ConcurrentHashMap map = new ConcurrentHashMap(5); + assertTrue(map.isEmpty()); + map.put(one, "A"); + map.put(two, "B"); + map.put(three, "C"); + map.put(four, "D"); + map.put(five, "E"); + assertFalse(map.isEmpty()); + assertEquals(5, map.size()); + return map; + } + + /** + * clear removes all pairs + */ + public void testClear() { + ConcurrentHashMap map = map5(); + map.clear(); + assertEquals(map.size(), 0); + } + + /** + * Maps with same contents are equal + */ + public void testEquals() { + ConcurrentHashMap map1 = map5(); + ConcurrentHashMap map2 = map5(); + assertEquals(map1, map2); + assertEquals(map2, map1); + map1.clear(); + assertFalse(map1.equals(map2)); + assertFalse(map2.equals(map1)); + } + + /** + * contains returns true for contained value + */ + public void testContains() { + ConcurrentHashMap map = map5(); + assertTrue(map.contains("A")); + assertFalse(map.contains("Z")); + } + + /** + * containsKey returns true for contained key + */ + public void testContainsKey() { + ConcurrentHashMap map = map5(); + assertTrue(map.containsKey(one)); + assertFalse(map.containsKey(zero)); + } + + /** + * containsValue returns true for held values + */ + public void testContainsValue() { + ConcurrentHashMap map = map5(); + assertTrue(map.contains("A")); + assertFalse(map.contains("Z")); + } + + /** + * enumeration returns an enumeration containing the correct + * elements + */ + public void testEnumeration() { + ConcurrentHashMap map = map5(); + Enumeration e = map.elements(); + int count = 0; + while(e.hasMoreElements()){ + count++; + e.nextElement(); + } + assertEquals(5, count); + } + + /** + * Clone creates an equal map + */ + public void testClone() { + // BEGIN android-changed + MyConcurrentHashMap map =myMap5(); + try { + MyConcurrentHashMap m2 = (MyConcurrentHashMap)(map.clone()); + assertEquals(map, m2); + } catch (CloneNotSupportedException e) { + fail("clone not supported"); + } + // END android-changed + } + + /** + * get returns the correct element at the given key, + * or null if not present + */ + public void testGet() { + ConcurrentHashMap map = map5(); + assertEquals("A", (String)map.get(one)); + ConcurrentHashMap empty = new ConcurrentHashMap(); + assertNull(map.get("anything")); + } + + /** + * isEmpty is true of empty map and false for non-empty + */ + public void testIsEmpty() { + ConcurrentHashMap empty = new ConcurrentHashMap(); + ConcurrentHashMap map = map5(); + assertTrue(empty.isEmpty()); + assertFalse(map.isEmpty()); + } + + /** + * keys returns an enumeration containing all the keys from the map + */ + public void testKeys() { + ConcurrentHashMap map = map5(); + Enumeration e = map.keys(); + int count = 0; + while(e.hasMoreElements()){ + count++; + e.nextElement(); + } + assertEquals(5, count); + } + + /** + * keySet returns a Set containing all the keys + */ + public void testKeySet() { + ConcurrentHashMap map = map5(); + Set s = map.keySet(); + assertEquals(5, s.size()); + assertTrue(s.contains(one)); + assertTrue(s.contains(two)); + assertTrue(s.contains(three)); + assertTrue(s.contains(four)); + assertTrue(s.contains(five)); + } + + /** + * values collection contains all values + */ + public void testValues() { + ConcurrentHashMap map = map5(); + Collection s = map.values(); + assertEquals(5, s.size()); + assertTrue(s.contains("A")); + assertTrue(s.contains("B")); + assertTrue(s.contains("C")); + assertTrue(s.contains("D")); + assertTrue(s.contains("E")); + } + + /** + * entrySet contains all pairs + */ + public void testEntrySet() { + ConcurrentHashMap map = map5(); + Set s = map.entrySet(); + assertEquals(5, s.size()); + Iterator it = s.iterator(); + while (it.hasNext()) { + Map.Entry e = (Map.Entry) it.next(); + assertTrue( + (e.getKey().equals(one) && e.getValue().equals("A")) || + (e.getKey().equals(two) && e.getValue().equals("B")) || + (e.getKey().equals(three) && e.getValue().equals("C")) || + (e.getKey().equals(four) && e.getValue().equals("D")) || + (e.getKey().equals(five) && e.getValue().equals("E"))); + } + } + + /** + * putAll adds all key-value pairs from the given map + */ + public void testPutAll() { + ConcurrentHashMap empty = new ConcurrentHashMap(); + ConcurrentHashMap map = map5(); + empty.putAll(map); + assertEquals(5, empty.size()); + assertTrue(empty.containsKey(one)); + assertTrue(empty.containsKey(two)); + assertTrue(empty.containsKey(three)); + assertTrue(empty.containsKey(four)); + assertTrue(empty.containsKey(five)); + } + + /** + * putIfAbsent works when the given key is not present + */ + public void testPutIfAbsent() { + ConcurrentHashMap map = map5(); + map.putIfAbsent(six, "Z"); + assertTrue(map.containsKey(six)); + } + + /** + * putIfAbsent does not add the pair if the key is already present + */ + public void testPutIfAbsent2() { + ConcurrentHashMap map = map5(); + assertEquals("A", map.putIfAbsent(one, "Z")); + } + + /** + * replace fails when the given key is not present + */ + public void testReplace() { + ConcurrentHashMap map = map5(); + assertNull(map.replace(six, "Z")); + assertFalse(map.containsKey(six)); + } + + /** + * replace succeeds if the key is already present + */ + public void testReplace2() { + ConcurrentHashMap map = map5(); + assertNotNull(map.replace(one, "Z")); + assertEquals("Z", map.get(one)); + } + + + /** + * replace value fails when the given key not mapped to expected value + */ + public void testReplaceValue() { + ConcurrentHashMap map = map5(); + assertEquals("A", map.get(one)); + assertFalse(map.replace(one, "Z", "Z")); + assertEquals("A", map.get(one)); + } + + /** + * replace value succeeds when the given key mapped to expected value + */ + public void testReplaceValue2() { + ConcurrentHashMap map = map5(); + assertEquals("A", map.get(one)); + assertTrue(map.replace(one, "A", "Z")); + assertEquals("Z", map.get(one)); + } + + + /** + * remove removes the correct key-value pair from the map + */ + public void testRemove() { + ConcurrentHashMap map = map5(); + map.remove(five); + assertEquals(4, map.size()); + assertFalse(map.containsKey(five)); + } + + /** + * remove(key,value) removes only if pair present + */ + public void testRemove2() { + ConcurrentHashMap map = map5(); + map.remove(five, "E"); + assertEquals(4, map.size()); + assertFalse(map.containsKey(five)); + map.remove(four, "A"); + assertEquals(4, map.size()); + assertTrue(map.containsKey(four)); + + } + + /** + * size returns the correct values + */ + public void testSize() { + ConcurrentHashMap map = map5(); + ConcurrentHashMap empty = new ConcurrentHashMap(); + assertEquals(0, empty.size()); + assertEquals(5, map.size()); + } + + /** + * toString contains toString of elements + */ + public void testToString() { + ConcurrentHashMap map = map5(); + String s = map.toString(); + for (int i = 1; i <= 5; ++i) { + assertTrue(s.indexOf(String.valueOf(i)) >= 0); + } + } + + // Exception tests + + /** + * Cannot create with negative capacity + */ + public void testConstructor1() { + try { + new ConcurrentHashMap(-1,0,1); + shouldThrow(); + } catch(IllegalArgumentException e){} + } + + /** + * Cannot create with negative concurrency level + */ + public void testConstructor2() { + try { + new ConcurrentHashMap(1,0,-1); + shouldThrow(); + } catch(IllegalArgumentException e){} + } + + /** + * Cannot create with only negative capacity + */ + public void testConstructor3() { + try { + new ConcurrentHashMap(-1); + shouldThrow(); + } catch(IllegalArgumentException e){} + } + + /** + * get(null) throws NPE + */ + public void testGet_NullPointerException() { + try { + ConcurrentHashMap c = new ConcurrentHashMap(5); + c.get(null); + shouldThrow(); + } catch(NullPointerException e){} + } + + /** + * containsKey(null) throws NPE + */ + public void testContainsKey_NullPointerException() { + try { + ConcurrentHashMap c = new ConcurrentHashMap(5); + c.containsKey(null); + shouldThrow(); + } catch(NullPointerException e){} + } + + /** + * containsValue(null) throws NPE + */ + public void testContainsValue_NullPointerException() { + try { + ConcurrentHashMap c = new ConcurrentHashMap(5); + c.containsValue(null); + shouldThrow(); + } catch(NullPointerException e){} + } + + /** + * contains(null) throws NPE + */ + public void testContains_NullPointerException() { + try { + ConcurrentHashMap c = new ConcurrentHashMap(5); + c.contains(null); + shouldThrow(); + } catch(NullPointerException e){} + } + + /** + * put(null,x) throws NPE + */ + public void testPut1_NullPointerException() { + try { + ConcurrentHashMap c = new ConcurrentHashMap(5); + c.put(null, "whatever"); + shouldThrow(); + } catch(NullPointerException e){} + } + + /** + * put(x, null) throws NPE + */ + public void testPut2_NullPointerException() { + try { + ConcurrentHashMap c = new ConcurrentHashMap(5); + c.put("whatever", null); + shouldThrow(); + } catch(NullPointerException e){} + } + + /** + * putIfAbsent(null, x) throws NPE + */ + public void testPutIfAbsent1_NullPointerException() { + try { + ConcurrentHashMap c = new ConcurrentHashMap(5); + c.putIfAbsent(null, "whatever"); + shouldThrow(); + } catch(NullPointerException e){} + } + + /** + * replace(null, x) throws NPE + */ + public void testReplace_NullPointerException() { + try { + ConcurrentHashMap c = new ConcurrentHashMap(5); + c.replace(null, "whatever"); + shouldThrow(); + } catch(NullPointerException e){} + } + + /** + * replace(null, x, y) throws NPE + */ + public void testReplaceValue_NullPointerException() { + try { + ConcurrentHashMap c = new ConcurrentHashMap(5); + c.replace(null, one, "whatever"); + shouldThrow(); + } catch(NullPointerException e){} + } + + /** + * putIfAbsent(x, null) throws NPE + */ + public void testPutIfAbsent2_NullPointerException() { + try { + ConcurrentHashMap c = new ConcurrentHashMap(5); + c.putIfAbsent("whatever", null); + shouldThrow(); + } catch(NullPointerException e){} + } + + + /** + * replace(x, null) throws NPE + */ + public void testReplace2_NullPointerException() { + try { + ConcurrentHashMap c = new ConcurrentHashMap(5); + c.replace("whatever", null); + shouldThrow(); + } catch(NullPointerException e){} + } + + /** + * replace(x, null, y) throws NPE + */ + public void testReplaceValue2_NullPointerException() { + try { + ConcurrentHashMap c = new ConcurrentHashMap(5); + c.replace("whatever", null, "A"); + shouldThrow(); + } catch(NullPointerException e){} + } + + /** + * replace(x, y, null) throws NPE + */ + public void testReplaceValue3_NullPointerException() { + try { + ConcurrentHashMap c = new ConcurrentHashMap(5); + c.replace("whatever", one, null); + shouldThrow(); + } catch(NullPointerException e){} + } + + + /** + * remove(null) throws NPE + */ + public void testRemove1_NullPointerException() { + try { + ConcurrentHashMap c = new ConcurrentHashMap(5); + c.put("sadsdf", "asdads"); + c.remove(null); + shouldThrow(); + } catch(NullPointerException e){} + } + + /** + * remove(null, x) throws NPE + */ + public void testRemove2_NullPointerException() { + try { + ConcurrentHashMap c = new ConcurrentHashMap(5); + c.put("sadsdf", "asdads"); + c.remove(null, "whatever"); + shouldThrow(); + } catch(NullPointerException e){} + } + + /** + * A deserialized map equals original + */ + public void testSerialization() { + ConcurrentHashMap q = map5(); + + try { + ByteArrayOutputStream bout = new ByteArrayOutputStream(10000); + ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout)); + out.writeObject(q); + out.close(); + + ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); + ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin)); + ConcurrentHashMap r = (ConcurrentHashMap)in.readObject(); + assertEquals(q.size(), r.size()); + assertTrue(q.equals(r)); + assertTrue(r.equals(q)); + } catch(Exception e){ + e.printStackTrace(); + unexpectedException(); + } + } + + + /** + * SetValue of an EntrySet entry sets value in the map. + */ + public void testSetValueWriteThrough() { + // Adapted from a bug report by Eric Zoerner + ConcurrentHashMap map = new ConcurrentHashMap(2, 5.0f, 1); + assertTrue(map.isEmpty()); + for (int i = 0; i < 20; i++) + map.put(new Integer(i), new Integer(i)); + assertFalse(map.isEmpty()); + Map.Entry entry1 = (Map.Entry)map.entrySet().iterator().next(); + + // assert that entry1 is not 16 + assertTrue("entry is 16, test not valid", + !entry1.getKey().equals(new Integer(16))); + + // remove 16 (a different key) from map + // which just happens to cause entry1 to be cloned in map + map.remove(new Integer(16)); + entry1.setValue("XYZ"); + assertTrue(map.containsValue("XYZ")); // fails + } + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentLinkedQueueTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentLinkedQueueTest.java new file mode 100755 index 0000000..8d8e13b --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentLinkedQueueTest.java @@ -0,0 +1,537 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.*; +import java.util.concurrent.*; +import java.io.*; + +public class ConcurrentLinkedQueueTest extends JSR166TestCase { + + public static void main(String[] args) { + junit.textui.TestRunner.run (suite()); + } + + public static Test suite() { + return new TestSuite(ConcurrentLinkedQueueTest.class); + } + + /** + * Create a queue of given size containing consecutive + * Integers 0 ... n. + */ + private ConcurrentLinkedQueue populatedQueue(int n) { + ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); + assertTrue(q.isEmpty()); + for(int i = 0; i < n; ++i) + assertTrue(q.offer(new Integer(i))); + assertFalse(q.isEmpty()); + assertEquals(n, q.size()); + return q; + } + + /** + * new queue is empty + */ + public void testConstructor1() { + assertEquals(0, new ConcurrentLinkedQueue().size()); + } + + /** + * Initializing from null Collection throws NPE + */ + public void testConstructor3() { + try { + ConcurrentLinkedQueue q = new ConcurrentLinkedQueue((Collection)null); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * Initializing from Collection of null elements throws NPE + */ + public void testConstructor4() { + try { + Integer[] ints = new Integer[SIZE]; + ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(Arrays.asList(ints)); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * Initializing from Collection with some null elements throws NPE + */ + public void testConstructor5() { + try { + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE-1; ++i) + ints[i] = new Integer(i); + ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(Arrays.asList(ints)); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * Queue contains all elements of collection used to initialize + */ + public void testConstructor6() { + try { + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE; ++i) + ints[i] = new Integer(i); + ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(Arrays.asList(ints)); + for (int i = 0; i < SIZE; ++i) + assertEquals(ints[i], q.poll()); + } + finally {} + } + + /** + * isEmpty is true before add, false after + */ + public void testEmpty() { + ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); + assertTrue(q.isEmpty()); + q.add(one); + assertFalse(q.isEmpty()); + q.add(two); + q.remove(); + q.remove(); + assertTrue(q.isEmpty()); + } + + /** + * size changes when elements added and removed + */ + public void testSize() { + ConcurrentLinkedQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(SIZE-i, q.size()); + q.remove(); + } + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.size()); + q.add(new Integer(i)); + } + } + + /** + * offer(null) throws NPE + */ + public void testOfferNull() { + try { + ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); + q.offer(null); + shouldThrow(); + } catch (NullPointerException success) { } + } + + /** + * add(null) throws NPE + */ + public void testAddNull() { + try { + ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); + q.add(null); + shouldThrow(); + } catch (NullPointerException success) { } + } + + + /** + * Offer returns true + */ + public void testOffer() { + ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); + assertTrue(q.offer(zero)); + assertTrue(q.offer(one)); + } + + /** + * add returns true + */ + public void testAdd() { + ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.size()); + assertTrue(q.add(new Integer(i))); + } + } + + /** + * addAll(null) throws NPE + */ + public void testAddAll1() { + try { + ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); + q.addAll(null); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * addAll(this) throws IAE + */ + public void testAddAllSelf() { + try { + ConcurrentLinkedQueue q = populatedQueue(SIZE); + q.addAll(q); + shouldThrow(); + } + catch (IllegalArgumentException success) {} + } + + /** + * addAll of a collection with null elements throws NPE + */ + public void testAddAll2() { + try { + ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); + Integer[] ints = new Integer[SIZE]; + q.addAll(Arrays.asList(ints)); + shouldThrow(); + } + catch (NullPointerException success) {} + } + /** + * addAll of a collection with any null elements throws NPE after + * possibly adding some elements + */ + public void testAddAll3() { + try { + ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE-1; ++i) + ints[i] = new Integer(i); + q.addAll(Arrays.asList(ints)); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * Queue contains all elements, in traversal order, of successful addAll + */ + public void testAddAll5() { + try { + Integer[] empty = new Integer[0]; + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE; ++i) + ints[i] = new Integer(i); + ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); + assertFalse(q.addAll(Arrays.asList(empty))); + assertTrue(q.addAll(Arrays.asList(ints))); + for (int i = 0; i < SIZE; ++i) + assertEquals(ints[i], q.poll()); + } + finally {} + } + + /** + * poll succeeds unless empty + */ + public void testPoll() { + ConcurrentLinkedQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.poll()).intValue()); + } + assertNull(q.poll()); + } + + /** + * peek returns next element, or null if empty + */ + public void testPeek() { + ConcurrentLinkedQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.peek()).intValue()); + q.poll(); + assertTrue(q.peek() == null || + i != ((Integer)q.peek()).intValue()); + } + assertNull(q.peek()); + } + + /** + * element returns next element, or throws NSEE if empty + */ + public void testElement() { + ConcurrentLinkedQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.element()).intValue()); + q.poll(); + } + try { + q.element(); + shouldThrow(); + } + catch (NoSuchElementException success) {} + } + + /** + * remove removes next element, or throws NSEE if empty + */ + public void testRemove() { + ConcurrentLinkedQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.remove()).intValue()); + } + try { + q.remove(); + shouldThrow(); + } catch (NoSuchElementException success){ + } + } + + /** + * remove(x) removes x and returns true if present + */ + public void testRemoveElement() { + ConcurrentLinkedQueue q = populatedQueue(SIZE); + for (int i = 1; i < SIZE; i+=2) { + assertTrue(q.remove(new Integer(i))); + } + for (int i = 0; i < SIZE; i+=2) { + assertTrue(q.remove(new Integer(i))); + assertFalse(q.remove(new Integer(i+1))); + } + assertTrue(q.isEmpty()); + } + + /** + * contains(x) reports true when elements added but not yet removed + */ + public void testContains() { + ConcurrentLinkedQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertTrue(q.contains(new Integer(i))); + q.poll(); + assertFalse(q.contains(new Integer(i))); + } + } + + /** + * clear removes all elements + */ + public void testClear() { + ConcurrentLinkedQueue q = populatedQueue(SIZE); + q.clear(); + assertTrue(q.isEmpty()); + assertEquals(0, q.size()); + q.add(one); + assertFalse(q.isEmpty()); + q.clear(); + assertTrue(q.isEmpty()); + } + + /** + * containsAll(c) is true when c contains a subset of elements + */ + public void testContainsAll() { + ConcurrentLinkedQueue q = populatedQueue(SIZE); + ConcurrentLinkedQueue p = new ConcurrentLinkedQueue(); + for (int i = 0; i < SIZE; ++i) { + assertTrue(q.containsAll(p)); + assertFalse(p.containsAll(q)); + p.add(new Integer(i)); + } + assertTrue(p.containsAll(q)); + } + + /** + * retainAll(c) retains only those elements of c and reports true if change + */ + public void testRetainAll() { + ConcurrentLinkedQueue q = populatedQueue(SIZE); + ConcurrentLinkedQueue p = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + boolean changed = q.retainAll(p); + if (i == 0) + assertFalse(changed); + else + assertTrue(changed); + + assertTrue(q.containsAll(p)); + assertEquals(SIZE-i, q.size()); + p.remove(); + } + } + + /** + * removeAll(c) removes only those elements of c and reports true if changed + */ + public void testRemoveAll() { + for (int i = 1; i < SIZE; ++i) { + ConcurrentLinkedQueue q = populatedQueue(SIZE); + ConcurrentLinkedQueue p = populatedQueue(i); + assertTrue(q.removeAll(p)); + assertEquals(SIZE-i, q.size()); + for (int j = 0; j < i; ++j) { + Integer I = (Integer)(p.remove()); + assertFalse(q.contains(I)); + } + } + } + + /** + * toArray contains all elements + */ + public void testToArray() { + ConcurrentLinkedQueue q = populatedQueue(SIZE); + Object[] o = q.toArray(); + Arrays.sort(o); + for(int i = 0; i < o.length; i++) + assertEquals(o[i], q.poll()); + } + + /** + * toArray(a) contains all elements + */ + public void testToArray2() { + ConcurrentLinkedQueue q = populatedQueue(SIZE); + Integer[] ints = new Integer[SIZE]; + ints = (Integer[])q.toArray(ints); + Arrays.sort(ints); + for(int i = 0; i < ints.length; i++) + assertEquals(ints[i], q.poll()); + } + + /** + * toArray(null) throws NPE + */ + public void testToArray_BadArg() { + try { + ConcurrentLinkedQueue q = populatedQueue(SIZE); + Object o[] = q.toArray(null); + shouldThrow(); + } catch(NullPointerException success){} + } + + /** + * toArray with incompatible array type throws CCE + */ + public void testToArray1_BadArg() { + try { + ConcurrentLinkedQueue q = populatedQueue(SIZE); + Object o[] = q.toArray(new String[10] ); + shouldThrow(); + } catch(ArrayStoreException success){} + } + + /** + * iterator iterates through all elements + */ + public void testIterator() { + ConcurrentLinkedQueue q = populatedQueue(SIZE); + int i = 0; + Iterator it = q.iterator(); + while(it.hasNext()) { + assertTrue(q.contains(it.next())); + ++i; + } + assertEquals(i, SIZE); + } + + /** + * iterator ordering is FIFO + */ + public void testIteratorOrdering() { + final ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); + q.add(one); + q.add(two); + q.add(three); + + int k = 0; + for (Iterator it = q.iterator(); it.hasNext();) { + int i = ((Integer)(it.next())).intValue(); + assertEquals(++k, i); + } + + assertEquals(3, k); + } + + /** + * Modifications do not cause iterators to fail + */ + public void testWeaklyConsistentIteration () { + final ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); + q.add(one); + q.add(two); + q.add(three); + + try { + for (Iterator it = q.iterator(); it.hasNext();) { + q.remove(); + it.next(); + } + } + catch (ConcurrentModificationException e) { + shouldThrow(); + } + + assertEquals("queue should be empty again", 0, q.size()); + } + + /** + * iterator.remove removes current element + */ + public void testIteratorRemove () { + final ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); + q.add(one); + q.add(two); + q.add(three); + Iterator it = q.iterator(); + it.next(); + it.remove(); + it = q.iterator(); + assertEquals(it.next(), two); + assertEquals(it.next(), three); + assertFalse(it.hasNext()); + } + + + /** + * toString contains toStrings of elements + */ + public void testToString() { + ConcurrentLinkedQueue q = populatedQueue(SIZE); + String s = q.toString(); + for (int i = 0; i < SIZE; ++i) { + assertTrue(s.indexOf(String.valueOf(i)) >= 0); + } + } + + /** + * A deserialized serialized queue has same elements in same order + */ + public void testSerialization() { + ConcurrentLinkedQueue q = populatedQueue(SIZE); + try { + ByteArrayOutputStream bout = new ByteArrayOutputStream(10000); + ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout)); + out.writeObject(q); + out.close(); + + ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); + ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin)); + ConcurrentLinkedQueue r = (ConcurrentLinkedQueue)in.readObject(); + assertEquals(q.size(), r.size()); + while (!q.isEmpty()) + assertEquals(q.remove(), r.remove()); + } catch(Exception e){ + unexpectedException(); + } + } + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/CopyOnWriteArrayListTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/CopyOnWriteArrayListTest.java new file mode 100755 index 0000000..d208039 --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/CopyOnWriteArrayListTest.java @@ -0,0 +1,623 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.*; +import java.util.concurrent.*; +import java.io.*; + +public class CopyOnWriteArrayListTest extends JSR166TestCase{ + + public static void main(String[] args) { + junit.textui.TestRunner.run (suite()); + } + + public static Test suite() { + return new TestSuite(CopyOnWriteArrayListTest.class); + } + + static CopyOnWriteArrayList populatedArray(int n){ + CopyOnWriteArrayList a = new CopyOnWriteArrayList(); + assertTrue(a.isEmpty()); + for (int i = 0; i < n; ++i) + a.add(new Integer(i)); + assertFalse(a.isEmpty()); + assertEquals(n, a.size()); + return a; + } + + + /** + * a new list is empty + */ + public void testConstructor() { + CopyOnWriteArrayList a = new CopyOnWriteArrayList(); + assertTrue(a.isEmpty()); + } + + /** + * new list contains all elements of initializing array + */ + public void testConstructor2() { + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE-1; ++i) + ints[i] = new Integer(i); + CopyOnWriteArrayList a = new CopyOnWriteArrayList(ints); + for (int i = 0; i < SIZE; ++i) + assertEquals(ints[i], a.get(i)); + } + + /** + * new list contains all elements of initializing collection + */ + public void testConstructor3() { + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE-1; ++i) + ints[i] = new Integer(i); + CopyOnWriteArrayList a = new CopyOnWriteArrayList(Arrays.asList(ints)); + for (int i = 0; i < SIZE; ++i) + assertEquals(ints[i], a.get(i)); + } + + + /** + * addAll adds each element from the given collection + */ + public void testAddAll() { + CopyOnWriteArrayList full = populatedArray(3); + Vector v = new Vector(); + v.add(three); + v.add(four); + v.add(five); + full.addAll(v); + assertEquals(6, full.size()); + } + + /** + * addAllAbsent adds each element from the given collection that did not + * already exist in the List + */ + public void testAddAllAbsent() { + CopyOnWriteArrayList full = populatedArray(3); + Vector v = new Vector(); + v.add(three); + v.add(four); + v.add(one); // will not add this element + full.addAllAbsent(v); + assertEquals(5, full.size()); + } + + /** + * addIfAbsent will not add the element if it already exists in the list + */ + public void testAddIfAbsent() { + CopyOnWriteArrayList full = populatedArray(SIZE); + full.addIfAbsent(one); + assertEquals(SIZE, full.size()); + } + + /** + * addIfAbsent adds the element when it does not exist in the list + */ + public void testAddIfAbsent2() { + CopyOnWriteArrayList full = populatedArray(SIZE); + full.addIfAbsent(three); + assertTrue(full.contains(three)); + } + + /** + * clear removes all elements from the list + */ + public void testClear() { + CopyOnWriteArrayList full = populatedArray(SIZE); + full.clear(); + assertEquals(0, full.size()); + } + + + /** + * Cloned list is equal + */ + public void testClone() { + CopyOnWriteArrayList l1 = populatedArray(SIZE); + CopyOnWriteArrayList l2 = (CopyOnWriteArrayList)(l1.clone()); + assertEquals(l1, l2); + l1.clear(); + assertFalse(l1.equals(l2)); + } + + /** + * contains is true for added elements + */ + public void testContains() { + CopyOnWriteArrayList full = populatedArray(3); + assertTrue(full.contains(one)); + assertFalse(full.contains(five)); + } + + /** + * adding at an index places it in the indicated index + */ + public void testAddIndex() { + CopyOnWriteArrayList full = populatedArray(3); + full.add(0, m1); + assertEquals(4, full.size()); + assertEquals(m1, full.get(0)); + assertEquals(zero, full.get(1)); + + full.add(2, m2); + assertEquals(5, full.size()); + assertEquals(m2, full.get(2)); + assertEquals(two, full.get(4)); + } + + /** + * lists with same elements are equal and have same hashCode + */ + public void testEquals() { + CopyOnWriteArrayList a = populatedArray(3); + CopyOnWriteArrayList b = populatedArray(3); + assertTrue(a.equals(b)); + assertTrue(b.equals(a)); + assertEquals(a.hashCode(), b.hashCode()); + a.add(m1); + assertFalse(a.equals(b)); + assertFalse(b.equals(a)); + b.add(m1); + assertTrue(a.equals(b)); + assertTrue(b.equals(a)); + assertEquals(a.hashCode(), b.hashCode()); + } + + + /** + * containsAll returns true for collection with subset of elements + */ + public void testContainsAll() { + CopyOnWriteArrayList full = populatedArray(3); + Vector v = new Vector(); + v.add(one); + v.add(two); + assertTrue(full.containsAll(v)); + v.add(six); + assertFalse(full.containsAll(v)); + } + + /** + * get returns the value at the given index + */ + public void testGet() { + CopyOnWriteArrayList full = populatedArray(3); + assertEquals(0, ((Integer)full.get(0)).intValue()); + } + + /** + * indexOf gives the index for the given object + */ + public void testIndexOf() { + CopyOnWriteArrayList full = populatedArray(3); + assertEquals(1, full.indexOf(one)); + assertEquals(-1, full.indexOf("puppies")); + } + + /** + * indexOf gives the index based on the given index + * at which to start searching + */ + public void testIndexOf2() { + CopyOnWriteArrayList full = populatedArray(3); + assertEquals(1, full.indexOf(one, 0)); + assertEquals(-1, full.indexOf(one, 2)); + } + + /** + * isEmpty returns true when empty, else false + */ + public void testIsEmpty() { + CopyOnWriteArrayList empty = new CopyOnWriteArrayList(); + CopyOnWriteArrayList full = populatedArray(SIZE); + assertTrue(empty.isEmpty()); + assertFalse(full.isEmpty()); + } + + /** + * iterator() returns an iterator containing the elements of the list + */ + public void testIterator() { + CopyOnWriteArrayList full = populatedArray(SIZE); + Iterator i = full.iterator(); + int j; + for(j = 0; i.hasNext(); j++) + assertEquals(j, ((Integer)i.next()).intValue()); + assertEquals(SIZE, j); + } + + /** + * iterator.remove throws UnsupportedOperationException + */ + public void testIteratorRemove () { + CopyOnWriteArrayList full = populatedArray(SIZE); + Iterator it = full.iterator(); + it.next(); + try { + it.remove(); + shouldThrow(); + } + catch (UnsupportedOperationException success) {} + } + + /** + * toString contains toString of elements + */ + public void testToString() { + CopyOnWriteArrayList full = populatedArray(3); + String s = full.toString(); + for (int i = 0; i < 3; ++i) { + assertTrue(s.indexOf(String.valueOf(i)) >= 0); + } + } + + /** + * lastIndexOf returns the index for the given object + */ + public void testLastIndexOf1() { + CopyOnWriteArrayList full = populatedArray(3); + full.add(one); + full.add(three); + assertEquals(3, full.lastIndexOf(one)); + assertEquals(-1, full.lastIndexOf(six)); + } + + /** + * lastIndexOf returns the index from the given starting point + */ + public void testlastIndexOf2() { + CopyOnWriteArrayList full = populatedArray(3); + full.add(one); + full.add(three); + assertEquals(3, full.lastIndexOf(one, 4)); + assertEquals(-1, full.lastIndexOf(three, 3)); + } + + /** + * listIterator traverses all elements + */ + public void testListIterator1() { + CopyOnWriteArrayList full = populatedArray(SIZE); + ListIterator i = full.listIterator(); + int j; + for(j = 0; i.hasNext(); j++) + assertEquals(j, ((Integer)i.next()).intValue()); + assertEquals(SIZE, j); + } + + /** + * listIterator only returns those elements after the given index + */ + public void testListIterator2() { + CopyOnWriteArrayList full = populatedArray(3); + ListIterator i = full.listIterator(1); + int j; + for(j = 0; i.hasNext(); j++) + assertEquals(j+1, ((Integer)i.next()).intValue()); + assertEquals(2, j); + } + + /** + * remove removes and returns the object at the given index + */ + public void testRemove() { + CopyOnWriteArrayList full = populatedArray(3); + assertEquals(two, full.remove(2)); + assertEquals(2, full.size()); + } + + /** + * removeAll removes all elements from the given collection + */ + public void testRemoveAll() { + CopyOnWriteArrayList full = populatedArray(3); + Vector v = new Vector(); + v.add(one); + v.add(two); + full.removeAll(v); + assertEquals(1, full.size()); + } + + /** + * set changes the element at the given index + */ + public void testSet() { + CopyOnWriteArrayList full = populatedArray(3); + assertEquals(two, full.set(2, four)); + assertEquals(4, ((Integer)full.get(2)).intValue()); + } + + /** + * size returns the number of elements + */ + public void testSize() { + CopyOnWriteArrayList empty = new CopyOnWriteArrayList(); + CopyOnWriteArrayList full = populatedArray(SIZE); + assertEquals(SIZE, full.size()); + assertEquals(0, empty.size()); + } + + /** + * toArray returns an Object array containing all elements from the list + */ + public void testToArray() { + CopyOnWriteArrayList full = populatedArray(3); + Object[] o = full.toArray(); + assertEquals(3, o.length); + assertEquals(0, ((Integer)o[0]).intValue()); + assertEquals(1, ((Integer)o[1]).intValue()); + assertEquals(2, ((Integer)o[2]).intValue()); + } + + /** + * toArray returns an Integer array containing all elements from + * the list + */ + public void testToArray2() { + CopyOnWriteArrayList full = populatedArray(3); + Integer[] i = new Integer[3]; + i = (Integer[])full.toArray(i); + assertEquals(3, i.length); + assertEquals(0, i[0].intValue()); + assertEquals(1, i[1].intValue()); + assertEquals(2, i[2].intValue()); + } + + + /** + * sublists contains elements at indexes offset from their base + */ + public void testSubList() { + CopyOnWriteArrayList a = populatedArray(10); + assertTrue(a.subList(1,1).isEmpty()); + for(int j = 0; j < 9; ++j) { + for(int i = j ; i < 10; ++i) { + List b = a.subList(j,i); + for(int k = j; k < i; ++k) { + assertEquals(new Integer(k), b.get(k-j)); + } + } + } + + List s = a.subList(2, 5); + assertEquals(s.size(), 3); + s.set(2, m1); + assertEquals(a.get(4), m1); + s.clear(); + assertEquals(a.size(), 7); + } + + // Exception tests + + /** + * toArray throws an ArrayStoreException when the given array + * can not store the objects inside the list + */ + public void testToArray_ArrayStoreException() { + try { + CopyOnWriteArrayList c = new CopyOnWriteArrayList(); + c.add("zfasdfsdf"); + c.add("asdadasd"); + c.toArray(new Long[5]); + shouldThrow(); + } catch(ArrayStoreException e){} + } + + /** + * get throws an IndexOutOfBoundsException on a negative index + */ + public void testGet1_IndexOutOfBoundsException() { + try { + CopyOnWriteArrayList c = new CopyOnWriteArrayList(); + c.get(-1); + shouldThrow(); + } catch(IndexOutOfBoundsException e){} + } + + /** + * get throws an IndexOutOfBoundsException on a too high index + */ + public void testGet2_IndexOutOfBoundsException() { + try { + CopyOnWriteArrayList c = new CopyOnWriteArrayList(); + c.add("asdasd"); + c.add("asdad"); + c.get(100); + shouldThrow(); + } catch(IndexOutOfBoundsException e){} + } + + /** + * set throws an IndexOutOfBoundsException on a negative index + */ + public void testSet1_IndexOutOfBoundsException() { + try { + CopyOnWriteArrayList c = new CopyOnWriteArrayList(); + c.set(-1,"qwerty"); + shouldThrow(); + } catch(IndexOutOfBoundsException e){} + } + + /** + * set throws an IndexOutOfBoundsException on a too high index + */ + public void testSet2() { + try { + CopyOnWriteArrayList c = new CopyOnWriteArrayList(); + c.add("asdasd"); + c.add("asdad"); + c.set(100, "qwerty"); + shouldThrow(); + } catch(IndexOutOfBoundsException e){} + } + + /** + * add throws an IndexOutOfBoundsException on a negative index + */ + public void testAdd1_IndexOutOfBoundsException() { + try { + CopyOnWriteArrayList c = new CopyOnWriteArrayList(); + c.add(-1,"qwerty"); + shouldThrow(); + } catch(IndexOutOfBoundsException e){} + } + + /** + * add throws an IndexOutOfBoundsException on a too high index + */ + public void testAdd2_IndexOutOfBoundsException() { + try { + CopyOnWriteArrayList c = new CopyOnWriteArrayList(); + c.add("asdasd"); + c.add("asdasdasd"); + c.add(100, "qwerty"); + shouldThrow(); + } catch(IndexOutOfBoundsException e){} + } + + /** + * remove throws an IndexOutOfBoundsException on a negative index + */ + public void testRemove1_IndexOutOfBounds() { + try { + CopyOnWriteArrayList c = new CopyOnWriteArrayList(); + c.remove(-1); + shouldThrow(); + } catch(IndexOutOfBoundsException e){} + } + + /** + * remove throws an IndexOutOfBoundsException on a too high index + */ + public void testRemove2_IndexOutOfBounds() { + try { + CopyOnWriteArrayList c = new CopyOnWriteArrayList(); + c.add("asdasd"); + c.add("adasdasd"); + c.remove(100); + shouldThrow(); + } catch(IndexOutOfBoundsException e){} + } + + /** + * addAll throws an IndexOutOfBoundsException on a negative index + */ + public void testAddAll1_IndexOutOfBoundsException() { + try { + CopyOnWriteArrayList c = new CopyOnWriteArrayList(); + c.addAll(-1,new LinkedList()); + shouldThrow(); + } catch(IndexOutOfBoundsException e){} + } + + /** + * addAll throws an IndexOutOfBoundsException on a too high index + */ + public void testAddAll2_IndexOutOfBoundsException() { + try { + CopyOnWriteArrayList c = new CopyOnWriteArrayList(); + c.add("asdasd"); + c.add("asdasdasd"); + c.addAll(100, new LinkedList()); + shouldThrow(); + } catch(IndexOutOfBoundsException e){} + } + + /** + * listIterator throws an IndexOutOfBoundsException on a negative index + */ + public void testListIterator1_IndexOutOfBoundsException() { + try { + CopyOnWriteArrayList c = new CopyOnWriteArrayList(); + c.listIterator(-1); + shouldThrow(); + } catch(IndexOutOfBoundsException e){} + } + + /** + * listIterator throws an IndexOutOfBoundsException on a too high index + */ + public void testListIterator2_IndexOutOfBoundsException() { + try { + CopyOnWriteArrayList c = new CopyOnWriteArrayList(); + c.add("adasd"); + c.add("asdasdas"); + c.listIterator(100); + shouldThrow(); + } catch(IndexOutOfBoundsException e){} + } + + /** + * subList throws an IndexOutOfBoundsException on a negative index + */ + public void testSubList1_IndexOutOfBoundsException() { + try { + CopyOnWriteArrayList c = new CopyOnWriteArrayList(); + c.subList(-1,100); + + shouldThrow(); + } catch(IndexOutOfBoundsException e){} + } + + /** + * subList throws an IndexOutOfBoundsException on a too high index + */ + public void testSubList2_IndexOutOfBoundsException() { + try { + CopyOnWriteArrayList c = new CopyOnWriteArrayList(); + c.add("asdasd"); + c.subList(1,100); + shouldThrow(); + } catch(IndexOutOfBoundsException e){} + } + + /** + * subList throws IndexOutOfBoundsException when the second index + * is lower then the first + */ + public void testSubList3_IndexOutOfBoundsException() { + try { + CopyOnWriteArrayList c = new CopyOnWriteArrayList(); + c.subList(3,1); + + shouldThrow(); + } catch(IndexOutOfBoundsException e){} + } + + /** + * a deserialized serialiszed list is equal + */ + public void testSerialization() { + CopyOnWriteArrayList q = populatedArray(SIZE); + + try { + ByteArrayOutputStream bout = new ByteArrayOutputStream(10000); + ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout)); + out.writeObject(q); + out.close(); + + ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); + ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin)); + CopyOnWriteArrayList r = (CopyOnWriteArrayList)in.readObject(); + assertEquals(q.size(), r.size()); + assertTrue(q.equals(r)); + assertTrue(r.equals(q)); + } catch(Exception e){ + unexpectedException(); + } + } + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/CopyOnWriteArraySetTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/CopyOnWriteArraySetTest.java new file mode 100755 index 0000000..809fc59 --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/CopyOnWriteArraySetTest.java @@ -0,0 +1,296 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.*; +import java.util.concurrent.*; +import java.io.*; + +public class CopyOnWriteArraySetTest extends JSR166TestCase { + public static void main(String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(CopyOnWriteArraySetTest.class); + } + + static CopyOnWriteArraySet populatedSet(int n){ + CopyOnWriteArraySet a = new CopyOnWriteArraySet(); + assertTrue(a.isEmpty()); + for (int i = 0; i < n; ++i) + a.add(new Integer(i)); + assertFalse(a.isEmpty()); + assertEquals(n, a.size()); + return a; + } + + /** + * Default-constructed set is empty + */ + public void testConstructor() { + CopyOnWriteArraySet a = new CopyOnWriteArraySet(); + assertTrue(a.isEmpty()); + } + + /** + * Collection-constructed set holds all of its elements + */ + public void testConstructor3() { + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE-1; ++i) + ints[i] = new Integer(i); + CopyOnWriteArraySet a = new CopyOnWriteArraySet(Arrays.asList(ints)); + for (int i = 0; i < SIZE; ++i) + assertTrue(a.contains(ints[i])); + } + + + /** + * addAll adds each element from the given collection + */ + public void testAddAll() { + CopyOnWriteArraySet full = populatedSet(3); + Vector v = new Vector(); + v.add(three); + v.add(four); + v.add(five); + full.addAll(v); + assertEquals(6, full.size()); + } + + /** + * addAll adds each element from the given collection that did not + * already exist in the set + */ + public void testAddAll2() { + CopyOnWriteArraySet full = populatedSet(3); + Vector v = new Vector(); + v.add(three); + v.add(four); + v.add(one); // will not add this element + full.addAll(v); + assertEquals(5, full.size()); + } + + /** + * add will not add the element if it already exists in the set + */ + public void testAdd2() { + CopyOnWriteArraySet full = populatedSet(3); + full.add(one); + assertEquals(3, full.size()); + } + + /** + * add adds the element when it does not exist + * in the set + */ + public void testAdd3() { + CopyOnWriteArraySet full = populatedSet(3); + full.add(three); + assertTrue(full.contains(three)); + } + + /** + * clear removes all elements from the set + */ + public void testClear() { + CopyOnWriteArraySet full = populatedSet(3); + full.clear(); + assertEquals(0, full.size()); + } + + /** + * contains returns true for added elements + */ + public void testContains() { + CopyOnWriteArraySet full = populatedSet(3); + assertTrue(full.contains(one)); + assertFalse(full.contains(five)); + } + + /** + * Sets with equal elements are equal + */ + public void testEquals() { + CopyOnWriteArraySet a = populatedSet(3); + CopyOnWriteArraySet b = populatedSet(3); + assertTrue(a.equals(b)); + assertTrue(b.equals(a)); + assertEquals(a.hashCode(), b.hashCode()); + a.add(m1); + assertFalse(a.equals(b)); + assertFalse(b.equals(a)); + b.add(m1); + assertTrue(a.equals(b)); + assertTrue(b.equals(a)); + assertEquals(a.hashCode(), b.hashCode()); + } + + + /** + * containsAll returns true for collections with subset of elements + */ + public void testContainsAll() { + CopyOnWriteArraySet full = populatedSet(3); + Vector v = new Vector(); + v.add(one); + v.add(two); + assertTrue(full.containsAll(v)); + v.add(six); + assertFalse(full.containsAll(v)); + } + + /** + * isEmpty is true when empty, else false + */ + public void testIsEmpty() { + CopyOnWriteArraySet empty = new CopyOnWriteArraySet(); + CopyOnWriteArraySet full = populatedSet(3); + assertTrue(empty.isEmpty()); + assertFalse(full.isEmpty()); + } + + /** + * iterator() returns an iterator containing the elements of the set + */ + public void testIterator() { + CopyOnWriteArraySet full = populatedSet(3); + Iterator i = full.iterator(); + int j; + for(j = 0; i.hasNext(); j++) + assertEquals(j, ((Integer)i.next()).intValue()); + assertEquals(3, j); + } + + /** + * iterator remove is unsupported + */ + public void testIteratorRemove () { + CopyOnWriteArraySet full = populatedSet(3); + Iterator it = full.iterator(); + it.next(); + try { + it.remove(); + shouldThrow(); + } + catch (UnsupportedOperationException success) {} + } + + /** + * toString holds toString of elements + */ + public void testToString() { + CopyOnWriteArraySet full = populatedSet(3); + String s = full.toString(); + for (int i = 0; i < 3; ++i) { + assertTrue(s.indexOf(String.valueOf(i)) >= 0); + } + } + + + /** + * removeAll removes all elements from the given collection + */ + public void testRemoveAll() { + CopyOnWriteArraySet full = populatedSet(3); + Vector v = new Vector(); + v.add(one); + v.add(two); + full.removeAll(v); + assertEquals(1, full.size()); + } + + + /** + * remove removes an element + */ + public void testRemove() { + CopyOnWriteArraySet full = populatedSet(3); + full.remove(one); + assertFalse(full.contains(one)); + assertEquals(2, full.size()); + } + + /** + * size returns the number of elements + */ + public void testSize() { + CopyOnWriteArraySet empty = new CopyOnWriteArraySet(); + CopyOnWriteArraySet full = populatedSet(3); + assertEquals(3, full.size()); + assertEquals(0, empty.size()); + } + + /** + * toArray returns an Object array containing all elements from the set + */ + public void testToArray() { + CopyOnWriteArraySet full = populatedSet(3); + Object[] o = full.toArray(); + assertEquals(3, o.length); + assertEquals(0, ((Integer)o[0]).intValue()); + assertEquals(1, ((Integer)o[1]).intValue()); + assertEquals(2, ((Integer)o[2]).intValue()); + } + + /** + * toArray returns an Integer array containing all elements from + * the set + */ + public void testToArray2() { + CopyOnWriteArraySet full = populatedSet(3); + Integer[] i = new Integer[3]; + i = (Integer[])full.toArray(i); + assertEquals(3, i.length); + assertEquals(0, i[0].intValue()); + assertEquals(1, i[1].intValue()); + assertEquals(2, i[2].intValue()); + } + + + /** + * toArray throws an ArrayStoreException when the given array can + * not store the objects inside the set + */ + public void testToArray_ArrayStoreException() { + try { + CopyOnWriteArraySet c = new CopyOnWriteArraySet(); + c.add("zfasdfsdf"); + c.add("asdadasd"); + c.toArray(new Long[5]); + shouldThrow(); + } catch(ArrayStoreException e){} + } + + /** + * A deserialized serialized set is equal + */ + public void testSerialization() { + CopyOnWriteArraySet q = populatedSet(SIZE); + + try { + ByteArrayOutputStream bout = new ByteArrayOutputStream(10000); + ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout)); + out.writeObject(q); + out.close(); + + ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); + ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin)); + CopyOnWriteArraySet r = (CopyOnWriteArraySet)in.readObject(); + assertEquals(q.size(), r.size()); + assertTrue(q.equals(r)); + assertTrue(r.equals(q)); + } catch(Exception e){ + unexpectedException(); + } + } + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/CountDownLatchTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/CountDownLatchTest.java new file mode 100755 index 0000000..0d69889 --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/CountDownLatchTest.java @@ -0,0 +1,206 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.*; +import java.util.concurrent.*; + +public class CountDownLatchTest extends JSR166TestCase { + public static void main(String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(CountDownLatchTest.class); + } + + /** + * negative constructor argument throws IAE + */ + public void testConstructor() { + try { + new CountDownLatch(-1); + shouldThrow(); + } catch(IllegalArgumentException success){} + } + + /** + * getCount returns initial count and decreases after countDown + */ + public void testGetCount() { + final CountDownLatch l = new CountDownLatch(2); + assertEquals(2, l.getCount()); + l.countDown(); + assertEquals(1, l.getCount()); + } + + /** + * countDown decrements count when positive and has no effect when zero + */ + public void testCountDown() { + final CountDownLatch l = new CountDownLatch(1); + assertEquals(1, l.getCount()); + l.countDown(); + assertEquals(0, l.getCount()); + l.countDown(); + assertEquals(0, l.getCount()); + } + + /** + * await returns after countDown to zero, but not before + */ + public void testAwait() { + final CountDownLatch l = new CountDownLatch(2); + + Thread t = new Thread(new Runnable() { + public void run() { + try { + threadAssertTrue(l.getCount() > 0); + l.await(); + threadAssertTrue(l.getCount() == 0); + } catch(InterruptedException e){ + threadUnexpectedException(); + } + } + }); + t.start(); + try { + assertEquals(l.getCount(), 2); + Thread.sleep(SHORT_DELAY_MS); + l.countDown(); + assertEquals(l.getCount(), 1); + l.countDown(); + assertEquals(l.getCount(), 0); + t.join(); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + + /** + * timed await returns after countDown to zero + */ + public void testTimedAwait() { + final CountDownLatch l = new CountDownLatch(2); + + Thread t = new Thread(new Runnable() { + public void run() { + try { + threadAssertTrue(l.getCount() > 0); + threadAssertTrue(l.await(SMALL_DELAY_MS, TimeUnit.MILLISECONDS)); + } catch(InterruptedException e){ + threadUnexpectedException(); + } + } + }); + t.start(); + try { + assertEquals(l.getCount(), 2); + Thread.sleep(SHORT_DELAY_MS); + l.countDown(); + assertEquals(l.getCount(), 1); + l.countDown(); + assertEquals(l.getCount(), 0); + t.join(); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * await throws IE if interrupted before counted down + */ + public void testAwait_InterruptedException() { + final CountDownLatch l = new CountDownLatch(1); + Thread t = new Thread(new Runnable() { + public void run() { + try { + threadAssertTrue(l.getCount() > 0); + l.await(); + threadShouldThrow(); + } catch(InterruptedException success){} + } + }); + t.start(); + try { + assertEquals(l.getCount(), 1); + t.interrupt(); + t.join(); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * timed await throws IE if interrupted before counted down + */ + public void testTimedAwait_InterruptedException() { + final CountDownLatch l = new CountDownLatch(1); + Thread t = new Thread(new Runnable() { + public void run() { + try { + threadAssertTrue(l.getCount() > 0); + l.await(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + threadShouldThrow(); + } catch(InterruptedException success){} + } + }); + t.start(); + try { + Thread.sleep(SHORT_DELAY_MS); + assertEquals(l.getCount(), 1); + t.interrupt(); + t.join(); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * timed await times out if not counted down before timeout + */ + public void testAwaitTimeout() { + final CountDownLatch l = new CountDownLatch(1); + Thread t = new Thread(new Runnable() { + public void run() { + try { + threadAssertTrue(l.getCount() > 0); + threadAssertFalse(l.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + threadAssertTrue(l.getCount() > 0); + } catch(InterruptedException ie){ + threadUnexpectedException(); + } + } + }); + t.start(); + try { + assertEquals(l.getCount(), 1); + t.join(); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * toString indicates current count + */ + public void testToString() { + CountDownLatch s = new CountDownLatch(2); + String us = s.toString(); + assertTrue(us.indexOf("Count = 2") >= 0); + s.countDown(); + String s1 = s.toString(); + assertTrue(s1.indexOf("Count = 1") >= 0); + s.countDown(); + String s2 = s.toString(); + assertTrue(s2.indexOf("Count = 0") >= 0); + } + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/CyclicBarrierTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/CyclicBarrierTest.java new file mode 100755 index 0000000..9eac1a7 --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/CyclicBarrierTest.java @@ -0,0 +1,379 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.*; +import java.util.concurrent.*; + +public class CyclicBarrierTest extends JSR166TestCase{ + public static void main(String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(CyclicBarrierTest.class); + } + + private volatile int countAction; + private class MyAction implements Runnable { + public void run() { ++countAction; } + } + + /** + * Creating with negative parties throws IAE + */ + public void testConstructor1() { + try { + new CyclicBarrier(-1, (Runnable)null); + shouldThrow(); + } catch(IllegalArgumentException e){} + } + + /** + * Creating with negative parties and no action throws IAE + */ + public void testConstructor2() { + try { + new CyclicBarrier(-1); + shouldThrow(); + } catch(IllegalArgumentException e){} + } + + /** + * getParties returns the number of parties given in constructor + */ + public void testGetParties() { + CyclicBarrier b = new CyclicBarrier(2); + assertEquals(2, b.getParties()); + assertEquals(0, b.getNumberWaiting()); + } + + /** + * A 1-party barrier triggers after single await + */ + public void testSingleParty() { + try { + CyclicBarrier b = new CyclicBarrier(1); + assertEquals(1, b.getParties()); + assertEquals(0, b.getNumberWaiting()); + b.await(); + b.await(); + assertEquals(0, b.getNumberWaiting()); + } + catch(Exception e) { + unexpectedException(); + } + } + + /** + * The supplied barrier action is run at barrier + */ + public void testBarrierAction() { + try { + countAction = 0; + CyclicBarrier b = new CyclicBarrier(1, new MyAction()); + assertEquals(1, b.getParties()); + assertEquals(0, b.getNumberWaiting()); + b.await(); + b.await(); + assertEquals(0, b.getNumberWaiting()); + assertEquals(countAction, 2); + } + catch(Exception e) { + unexpectedException(); + } + } + + /** + * A 2-party/thread barrier triggers after both threads invoke await + */ + public void testTwoParties() { + final CyclicBarrier b = new CyclicBarrier(2); + Thread t = new Thread(new Runnable() { + public void run() { + try { + b.await(); + b.await(); + b.await(); + b.await(); + } catch(Exception e){ + threadUnexpectedException(); + }}}); + + try { + t.start(); + b.await(); + b.await(); + b.await(); + b.await(); + t.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + + /** + * An interruption in one party causes others waiting in await to + * throw BrokenBarrierException + */ + public void testAwait1_Interrupted_BrokenBarrier() { + final CyclicBarrier c = new CyclicBarrier(3); + Thread t1 = new Thread(new Runnable() { + public void run() { + try { + c.await(); + threadShouldThrow(); + } catch(InterruptedException success){} + catch(Exception b){ + threadUnexpectedException(); + } + } + }); + Thread t2 = new Thread(new Runnable() { + public void run() { + try { + c.await(); + threadShouldThrow(); + } catch(BrokenBarrierException success){ + } catch(Exception i){ + threadUnexpectedException(); + } + } + }); + try { + t1.start(); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + t1.interrupt(); + t1.join(); + t2.join(); + } catch(InterruptedException e){ + unexpectedException(); + } + } + + /** + * An interruption in one party causes others waiting in timed await to + * throw BrokenBarrierException + */ + public void testAwait2_Interrupted_BrokenBarrier() { + final CyclicBarrier c = new CyclicBarrier(3); + Thread t1 = new Thread(new Runnable() { + public void run() { + try { + c.await(LONG_DELAY_MS, TimeUnit.MILLISECONDS); + threadShouldThrow(); + } catch(InterruptedException success){ + } catch(Exception b){ + threadUnexpectedException(); + } + } + }); + Thread t2 = new Thread(new Runnable() { + public void run() { + try { + c.await(LONG_DELAY_MS, TimeUnit.MILLISECONDS); + threadShouldThrow(); + } catch(BrokenBarrierException success){ + } catch(Exception i){ + threadUnexpectedException(); + } + } + }); + try { + t1.start(); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + t1.interrupt(); + t1.join(); + t2.join(); + } catch(InterruptedException e){ + unexpectedException(); + } + } + + /** + * A timeout in timed await throws TimeoutException + */ + public void testAwait3_TimeOutException() { + final CyclicBarrier c = new CyclicBarrier(2); + Thread t = new Thread(new Runnable() { + public void run() { + try { + c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS); + threadShouldThrow(); + } catch(TimeoutException success){ + } catch(Exception b){ + threadUnexpectedException(); + + } + } + }); + try { + t.start(); + t.join(); + } catch(InterruptedException e){ + unexpectedException(); + } + } + + /** + * A timeout in one party causes others waiting in timed await to + * throw BrokenBarrierException + */ + public void testAwait4_Timeout_BrokenBarrier() { + final CyclicBarrier c = new CyclicBarrier(3); + Thread t1 = new Thread(new Runnable() { + public void run() { + try { + c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS); + threadShouldThrow(); + } catch(TimeoutException success){ + } catch(Exception b){ + threadUnexpectedException(); + } + } + }); + Thread t2 = new Thread(new Runnable() { + public void run() { + try { + c.await(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + threadShouldThrow(); + } catch(BrokenBarrierException success){ + } catch(Exception i){ + threadUnexpectedException(); + } + } + }); + try { + t1.start(); + t2.start(); + t1.join(); + t2.join(); + } catch(InterruptedException e){ + unexpectedException(); + } + } + + /** + * A timeout in one party causes others waiting in await to + * throw BrokenBarrierException + */ + public void testAwait5_Timeout_BrokenBarrier() { + final CyclicBarrier c = new CyclicBarrier(3); + Thread t1 = new Thread(new Runnable() { + public void run() { + try { + c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS); + threadShouldThrow(); + } catch(TimeoutException success){ + } catch(Exception b){ + threadUnexpectedException(); + } + } + }); + Thread t2 = new Thread(new Runnable() { + public void run() { + try { + c.await(); + threadShouldThrow(); + } catch(BrokenBarrierException success){ + } catch(Exception i){ + threadUnexpectedException(); + } + } + }); + try { + t1.start(); + t2.start(); + t1.join(); + t2.join(); + } catch(InterruptedException e){ + unexpectedException(); + } + } + + /** + * A reset of an active barrier causes waiting threads to throw + * BrokenBarrierException + */ + public void testReset_BrokenBarrier() { + final CyclicBarrier c = new CyclicBarrier(3); + Thread t1 = new Thread(new Runnable() { + public void run() { + try { + c.await(); + threadShouldThrow(); + } catch(BrokenBarrierException success){} + catch(Exception b){ + threadUnexpectedException(); + } + } + }); + Thread t2 = new Thread(new Runnable() { + public void run() { + try { + c.await(); + threadShouldThrow(); + } catch(BrokenBarrierException success){ + } catch(Exception i){ + threadUnexpectedException(); + } + } + }); + try { + t1.start(); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + c.reset(); + t1.join(); + t2.join(); + } catch(InterruptedException e){ + unexpectedException(); + } + } + + /** + * A reset before threads enter barrier does not throw + * BrokenBarrierException + */ + public void testReset_NoBrokenBarrier() { + final CyclicBarrier c = new CyclicBarrier(3); + Thread t1 = new Thread(new Runnable() { + public void run() { + try { + c.await(); + } catch(Exception b){ + threadUnexpectedException(); + } + } + }); + Thread t2 = new Thread(new Runnable() { + public void run() { + try { + c.await(); + } catch(Exception i){ + threadUnexpectedException(); + } + } + }); + try { + c.reset(); + t1.start(); + t2.start(); + c.await(); + t1.join(); + t2.join(); + } catch(Exception e){ + unexpectedException(); + } + } + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/DelayQueueTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/DelayQueueTest.java new file mode 100755 index 0000000..e332513 --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/DelayQueueTest.java @@ -0,0 +1,985 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.*; +import java.util.concurrent.*; + +public class DelayQueueTest extends JSR166TestCase { + public static void main(String[] args) { + junit.textui.TestRunner.run (suite()); + } + + public static Test suite() { + return new TestSuite(DelayQueueTest.class); + } + + private static final int NOCAP = Integer.MAX_VALUE; + + /** + * A delayed implementation for testing. + * Most tests use Pseudodelays, where delays are all elapsed + * (so, no blocking solely for delays) but are still ordered + */ + static class PDelay implements Delayed { + int pseudodelay; + PDelay(int i) { pseudodelay = Integer.MIN_VALUE + i; } + // BEGIN android-changed + public int compareTo(Delayed y) { + int i = pseudodelay; + int j = ((PDelay)y).pseudodelay; + if (i < j) return -1; + if (i > j) return 1; + return 0; + } + // END android-changed + public int compareTo(PDelay y) { + int i = pseudodelay; + int j = ((PDelay)y).pseudodelay; + if (i < j) return -1; + if (i > j) return 1; + return 0; + } + + public boolean equals(Object other) { + return ((PDelay)other).pseudodelay == pseudodelay; + } + public boolean equals(PDelay other) { + return ((PDelay)other).pseudodelay == pseudodelay; + } + + + public long getDelay(TimeUnit ignore) { + return pseudodelay; + } + public int intValue() { + return pseudodelay; + } + + public String toString() { + return String.valueOf(pseudodelay); + } + } + + + /** + * Delayed implementation that actually delays + */ + static class NanoDelay implements Delayed { + long trigger; + NanoDelay(long i) { + trigger = System.nanoTime() + i; + } + // BEGIN android-changed + public int compareTo(Delayed y) { + long i = trigger; + long j = ((NanoDelay)y).trigger; + if (i < j) return -1; + if (i > j) return 1; + return 0; + } + // END android-changed + public int compareTo(NanoDelay y) { + long i = trigger; + long j = ((NanoDelay)y).trigger; + if (i < j) return -1; + if (i > j) return 1; + return 0; + } + + public boolean equals(Object other) { + return ((NanoDelay)other).trigger == trigger; + } + public boolean equals(NanoDelay other) { + return ((NanoDelay)other).trigger == trigger; + } + + public long getDelay(TimeUnit unit) { + long n = trigger - System.nanoTime(); + return unit.convert(n, TimeUnit.NANOSECONDS); + } + + public long getTriggerTime() { + return trigger; + } + + public String toString() { + return String.valueOf(trigger); + } + } + + + /** + * Create a queue of given size containing consecutive + * PDelays 0 ... n. + */ + private DelayQueue populatedQueue(int n) { + DelayQueue q = new DelayQueue(); + assertTrue(q.isEmpty()); + for(int i = n-1; i >= 0; i-=2) + assertTrue(q.offer(new PDelay(i))); + for(int i = (n & 1); i < n; i+=2) + assertTrue(q.offer(new PDelay(i))); + assertFalse(q.isEmpty()); + assertEquals(NOCAP, q.remainingCapacity()); + assertEquals(n, q.size()); + return q; + } + + /** + * A new queue has unbounded capacity + */ + public void testConstructor1() { + assertEquals(NOCAP, new DelayQueue().remainingCapacity()); + } + + /** + * Initializing from null Collection throws NPE + */ + public void testConstructor3() { + try { + DelayQueue q = new DelayQueue(null); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * Initializing from Collection of null elements throws NPE + */ + public void testConstructor4() { + try { + PDelay[] ints = new PDelay[SIZE]; + DelayQueue q = new DelayQueue(Arrays.asList(ints)); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * Initializing from Collection with some null elements throws NPE + */ + public void testConstructor5() { + try { + PDelay[] ints = new PDelay[SIZE]; + for (int i = 0; i < SIZE-1; ++i) + ints[i] = new PDelay(i); + DelayQueue q = new DelayQueue(Arrays.asList(ints)); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * Queue contains all elements of collection used to initialize + */ + public void testConstructor6() { + try { + PDelay[] ints = new PDelay[SIZE]; + for (int i = 0; i < SIZE; ++i) + ints[i] = new PDelay(i); + DelayQueue q = new DelayQueue(Arrays.asList(ints)); + for (int i = 0; i < SIZE; ++i) + assertEquals(ints[i], q.poll()); + } + finally {} + } + + /** + * isEmpty is true before add, false after + */ + public void testEmpty() { + DelayQueue q = new DelayQueue(); + assertTrue(q.isEmpty()); + assertEquals(NOCAP, q.remainingCapacity()); + q.add(new PDelay(1)); + assertFalse(q.isEmpty()); + q.add(new PDelay(2)); + q.remove(); + q.remove(); + assertTrue(q.isEmpty()); + } + + /** + * remainingCapacity does not change when elementa added or removed, + * but size does + */ + public void testRemainingCapacity() { + DelayQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(NOCAP, q.remainingCapacity()); + assertEquals(SIZE-i, q.size()); + q.remove(); + } + for (int i = 0; i < SIZE; ++i) { + assertEquals(NOCAP, q.remainingCapacity()); + assertEquals(i, q.size()); + q.add(new PDelay(i)); + } + } + + /** + * offer(null) throws NPE + */ + public void testOfferNull() { + try { + DelayQueue q = new DelayQueue(); + q.offer(null); + shouldThrow(); + } catch (NullPointerException success) { } + } + + /** + * add(null) throws NPE + */ + public void testAddNull() { + try { + DelayQueue q = new DelayQueue(); + q.add(null); + shouldThrow(); + } catch (NullPointerException success) { } + } + + /** + * offer non-null succeeds + */ + public void testOffer() { + DelayQueue q = new DelayQueue(); + assertTrue(q.offer(new PDelay(0))); + assertTrue(q.offer(new PDelay(1))); + } + + /** + * add succeeds + */ + public void testAdd() { + DelayQueue q = new DelayQueue(); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.size()); + assertTrue(q.add(new PDelay(i))); + } + } + + /** + * addAll(null) throws NPE + */ + public void testAddAll1() { + try { + DelayQueue q = new DelayQueue(); + q.addAll(null); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + + /** + * addAll(this) throws IAE + */ + public void testAddAllSelf() { + try { + DelayQueue q = populatedQueue(SIZE); + q.addAll(q); + shouldThrow(); + } + catch (IllegalArgumentException success) {} + } + + /** + * addAll of a collection with null elements throws NPE + */ + public void testAddAll2() { + try { + DelayQueue q = new DelayQueue(); + PDelay[] ints = new PDelay[SIZE]; + q.addAll(Arrays.asList(ints)); + shouldThrow(); + } + catch (NullPointerException success) {} + } + /** + * addAll of a collection with any null elements throws NPE after + * possibly adding some elements + */ + public void testAddAll3() { + try { + DelayQueue q = new DelayQueue(); + PDelay[] ints = new PDelay[SIZE]; + for (int i = 0; i < SIZE-1; ++i) + ints[i] = new PDelay(i); + q.addAll(Arrays.asList(ints)); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * Queue contains all elements of successful addAll + */ + public void testAddAll5() { + try { + PDelay[] empty = new PDelay[0]; + PDelay[] ints = new PDelay[SIZE]; + for (int i = SIZE-1; i >= 0; --i) + ints[i] = new PDelay(i); + DelayQueue q = new DelayQueue(); + assertFalse(q.addAll(Arrays.asList(empty))); + assertTrue(q.addAll(Arrays.asList(ints))); + for (int i = 0; i < SIZE; ++i) + assertEquals(ints[i], q.poll()); + } + finally {} + } + + /** + * put(null) throws NPE + */ + public void testPutNull() { + try { + DelayQueue q = new DelayQueue(); + q.put(null); + shouldThrow(); + } + catch (NullPointerException success){ + } + } + + /** + * all elements successfully put are contained + */ + public void testPut() { + try { + DelayQueue q = new DelayQueue(); + for (int i = 0; i < SIZE; ++i) { + PDelay I = new PDelay(i); + q.put(I); + assertTrue(q.contains(I)); + } + assertEquals(SIZE, q.size()); + } + finally { + } + } + + /** + * put doesn't block waiting for take + */ + public void testPutWithTake() { + final DelayQueue q = new DelayQueue(); + Thread t = new Thread(new Runnable() { + public void run() { + int added = 0; + try { + q.put(new PDelay(0)); + ++added; + q.put(new PDelay(0)); + ++added; + q.put(new PDelay(0)); + ++added; + q.put(new PDelay(0)); + ++added; + threadAssertTrue(added == 4); + } finally { + } + } + }); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + q.take(); + t.interrupt(); + t.join(); + } catch (Exception e){ + unexpectedException(); + } + } + + /** + * timed offer does not time out + */ + public void testTimedOffer() { + final DelayQueue q = new DelayQueue(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + q.put(new PDelay(0)); + q.put(new PDelay(0)); + threadAssertTrue(q.offer(new PDelay(0), SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + threadAssertTrue(q.offer(new PDelay(0), LONG_DELAY_MS, TimeUnit.MILLISECONDS)); + } finally { } + } + }); + + try { + t.start(); + Thread.sleep(SMALL_DELAY_MS); + t.interrupt(); + t.join(); + } catch (Exception e){ + unexpectedException(); + } + } + + /** + * take retrieves elements in priority order + */ + public void testTake() { + try { + DelayQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(new PDelay(i), ((PDelay)q.take())); + } + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * take blocks interruptibly when empty + */ + public void testTakeFromEmpty() { + final DelayQueue q = new DelayQueue(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + q.take(); + threadShouldThrow(); + } catch (InterruptedException success){ } + } + }); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } catch (Exception e){ + unexpectedException(); + } + } + + /** + * Take removes existing elements until empty, then blocks interruptibly + */ + public void testBlockingTake() { + Thread t = new Thread(new Runnable() { + public void run() { + try { + DelayQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + threadAssertEquals(new PDelay(i), ((PDelay)q.take())); + } + q.take(); + threadShouldThrow(); + } catch (InterruptedException success){ + } + }}); + t.start(); + try { + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } + catch (InterruptedException ie) { + unexpectedException(); + } + } + + + /** + * poll succeeds unless empty + */ + public void testPoll() { + DelayQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(new PDelay(i), ((PDelay)q.poll())); + } + assertNull(q.poll()); + } + + /** + * timed pool with zero timeout succeeds when non-empty, else times out + */ + public void testTimedPoll0() { + try { + DelayQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(new PDelay(i), ((PDelay)q.poll(0, TimeUnit.MILLISECONDS))); + } + assertNull(q.poll(0, TimeUnit.MILLISECONDS)); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * timed pool with nonzero timeout succeeds when non-empty, else times out + */ + public void testTimedPoll() { + try { + DelayQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(new PDelay(i), ((PDelay)q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS))); + } + assertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * Interrupted timed poll throws InterruptedException instead of + * returning timeout status + */ + public void testInterruptedTimedPoll() { + Thread t = new Thread(new Runnable() { + public void run() { + try { + DelayQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + threadAssertEquals(new PDelay(i), ((PDelay)q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS))); + } + threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + } catch (InterruptedException success){ + } + }}); + t.start(); + try { + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } + catch (InterruptedException ie) { + unexpectedException(); + } + } + + /** + * timed poll before a delayed offer fails; after offer succeeds; + * on interruption throws + */ + public void testTimedPollWithOffer() { + final DelayQueue q = new DelayQueue(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS); + q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS); + threadFail("Should block"); + } catch (InterruptedException success) { } + } + }); + try { + t.start(); + Thread.sleep(SMALL_DELAY_MS); + assertTrue(q.offer(new PDelay(0), SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + t.interrupt(); + t.join(); + } catch (Exception e){ + unexpectedException(); + } + } + + + /** + * peek returns next element, or null if empty + */ + public void testPeek() { + DelayQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(new PDelay(i), ((PDelay)q.peek())); + q.poll(); + assertTrue(q.peek() == null || + i != ((PDelay)q.peek()).intValue()); + } + assertNull(q.peek()); + } + + /** + * element returns next element, or throws NSEE if empty + */ + public void testElement() { + DelayQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(new PDelay(i), ((PDelay)q.element())); + q.poll(); + } + try { + q.element(); + shouldThrow(); + } + catch (NoSuchElementException success) {} + } + + /** + * remove removes next element, or throws NSEE if empty + */ + public void testRemove() { + DelayQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(new PDelay(i), ((PDelay)q.remove())); + } + try { + q.remove(); + shouldThrow(); + } catch (NoSuchElementException success){ + } + } + + /** + * remove(x) removes x and returns true if present + */ + public void testRemoveElement() { + DelayQueue q = populatedQueue(SIZE); + for (int i = 1; i < SIZE; i+=2) { + assertTrue(q.remove(new PDelay(i))); + } + for (int i = 0; i < SIZE; i+=2) { + assertTrue(q.remove(new PDelay(i))); + assertFalse(q.remove(new PDelay(i+1))); + } + assertTrue(q.isEmpty()); + } + + /** + * contains(x) reports true when elements added but not yet removed + */ + public void testContains() { + DelayQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertTrue(q.contains(new PDelay(i))); + q.poll(); + assertFalse(q.contains(new PDelay(i))); + } + } + + /** + * clear removes all elements + */ + public void testClear() { + DelayQueue q = populatedQueue(SIZE); + q.clear(); + assertTrue(q.isEmpty()); + assertEquals(0, q.size()); + assertEquals(NOCAP, q.remainingCapacity()); + q.add(new PDelay(1)); + assertFalse(q.isEmpty()); + q.clear(); + assertTrue(q.isEmpty()); + } + + /** + * containsAll(c) is true when c contains a subset of elements + */ + public void testContainsAll() { + DelayQueue q = populatedQueue(SIZE); + DelayQueue p = new DelayQueue(); + for (int i = 0; i < SIZE; ++i) { + assertTrue(q.containsAll(p)); + assertFalse(p.containsAll(q)); + p.add(new PDelay(i)); + } + assertTrue(p.containsAll(q)); + } + + /** + * retainAll(c) retains only those elements of c and reports true if changed + */ + public void testRetainAll() { + DelayQueue q = populatedQueue(SIZE); + DelayQueue p = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + boolean changed = q.retainAll(p); + if (i == 0) + assertFalse(changed); + else + assertTrue(changed); + + assertTrue(q.containsAll(p)); + assertEquals(SIZE-i, q.size()); + p.remove(); + } + } + + /** + * removeAll(c) removes only those elements of c and reports true if changed + */ + public void testRemoveAll() { + for (int i = 1; i < SIZE; ++i) { + DelayQueue q = populatedQueue(SIZE); + DelayQueue p = populatedQueue(i); + assertTrue(q.removeAll(p)); + assertEquals(SIZE-i, q.size()); + for (int j = 0; j < i; ++j) { + PDelay I = (PDelay)(p.remove()); + assertFalse(q.contains(I)); + } + } + } + + /** + * toArray contains all elements + */ + public void testToArray() { + DelayQueue q = populatedQueue(SIZE); + Object[] o = q.toArray(); + Arrays.sort(o); + try { + for(int i = 0; i < o.length; i++) + assertEquals(o[i], q.take()); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * toArray(a) contains all elements + */ + public void testToArray2() { + DelayQueue q = populatedQueue(SIZE); + PDelay[] ints = new PDelay[SIZE]; + ints = (PDelay[])q.toArray(ints); + Arrays.sort(ints); + try { + for(int i = 0; i < ints.length; i++) + assertEquals(ints[i], q.take()); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + + /** + * toArray(null) throws NPE + */ + public void testToArray_BadArg() { + try { + DelayQueue q = populatedQueue(SIZE); + Object o[] = q.toArray(null); + shouldThrow(); + } catch(NullPointerException success){} + } + + /** + * toArray with incompatible array type throws CCE + */ + public void testToArray1_BadArg() { + try { + DelayQueue q = populatedQueue(SIZE); + Object o[] = q.toArray(new String[10] ); + shouldThrow(); + } catch(ArrayStoreException success){} + } + + /** + * iterator iterates through all elements + */ + public void testIterator() { + DelayQueue q = populatedQueue(SIZE); + int i = 0; + Iterator it = q.iterator(); + while(it.hasNext()) { + assertTrue(q.contains(it.next())); + ++i; + } + assertEquals(i, SIZE); + } + + /** + * iterator.remove removes current element + */ + public void testIteratorRemove () { + final DelayQueue q = new DelayQueue(); + q.add(new PDelay(2)); + q.add(new PDelay(1)); + q.add(new PDelay(3)); + Iterator it = q.iterator(); + it.next(); + it.remove(); + it = q.iterator(); + assertEquals(it.next(), new PDelay(2)); + assertEquals(it.next(), new PDelay(3)); + assertFalse(it.hasNext()); + } + + + /** + * toString contains toStrings of elements + */ + public void testToString() { + DelayQueue q = populatedQueue(SIZE); + String s = q.toString(); + for (int i = 0; i < SIZE; ++i) { + assertTrue(s.indexOf(String.valueOf(Integer.MIN_VALUE+i)) >= 0); + } + } + + /** + * offer transfers elements across Executor tasks + */ + public void testPollInExecutor() { + final DelayQueue q = new DelayQueue(); + ExecutorService executor = Executors.newFixedThreadPool(2); + executor.execute(new Runnable() { + public void run() { + threadAssertNull(q.poll()); + try { + threadAssertTrue(null != q.poll(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS)); + threadAssertTrue(q.isEmpty()); + } + catch (InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + executor.execute(new Runnable() { + public void run() { + try { + Thread.sleep(SHORT_DELAY_MS); + q.put(new PDelay(1)); + } + catch (InterruptedException e) { + threadUnexpectedException(); + } + } + }); + joinPool(executor); + + } + + + /** + * Delayed actions do not occur until their delay elapses + */ + public void testDelay() { + DelayQueue q = new DelayQueue(); + NanoDelay[] elements = new NanoDelay[SIZE]; + for (int i = 0; i < SIZE; ++i) { + elements[i] = new NanoDelay(1000000000L + 1000000L * (SIZE - i)); + } + for (int i = 0; i < SIZE; ++i) { + q.add(elements[i]); + } + + try { + long last = 0; + for (int i = 0; i < SIZE; ++i) { + NanoDelay e = (NanoDelay)(q.take()); + long tt = e.getTriggerTime(); + assertTrue(tt <= System.nanoTime()); + if (i != 0) + assertTrue(tt >= last); + last = tt; + } + } + catch(InterruptedException ie) { + unexpectedException(); + } + } + + + /** + * drainTo(null) throws NPE + */ + public void testDrainToNull() { + DelayQueue q = populatedQueue(SIZE); + try { + q.drainTo(null); + shouldThrow(); + } catch(NullPointerException success) { + } + } + + /** + * drainTo(this) throws IAE + */ + public void testDrainToSelf() { + DelayQueue q = populatedQueue(SIZE); + try { + q.drainTo(q); + shouldThrow(); + } catch(IllegalArgumentException success) { + } + } + + /** + * drainTo(c) empties queue into another collection c + */ + public void testDrainTo() { + DelayQueue q = populatedQueue(SIZE); + ArrayList l = new ArrayList(); + q.drainTo(l); + assertEquals(q.size(), 0); + assertEquals(l.size(), SIZE); + } + + /** + * drainTo empties queue + */ + public void testDrainToWithActivePut() { + final DelayQueue q = populatedQueue(SIZE); + Thread t = new Thread(new Runnable() { + public void run() { + q.put(new PDelay(SIZE+1)); + } + }); + try { + t.start(); + ArrayList l = new ArrayList(); + q.drainTo(l); + assertTrue(l.size() >= SIZE); + t.join(); + assertTrue(q.size() + l.size() >= SIZE); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * drainTo(null, n) throws NPE + */ + public void testDrainToNullN() { + DelayQueue q = populatedQueue(SIZE); + try { + q.drainTo(null, 0); + shouldThrow(); + } catch(NullPointerException success) { + } + } + + /** + * drainTo(this, n) throws IAE + */ + public void testDrainToSelfN() { + DelayQueue q = populatedQueue(SIZE); + try { + q.drainTo(q, 0); + shouldThrow(); + } catch(IllegalArgumentException success) { + } + } + + /** + * drainTo(c, n) empties first max {n, size} elements of queue into c + */ + public void testDrainToN() { + for (int i = 0; i < SIZE + 2; ++i) { + DelayQueue q = populatedQueue(SIZE); + ArrayList l = new ArrayList(); + q.drainTo(l, i); + int k = (i < SIZE)? i : SIZE; + assertEquals(q.size(), SIZE-k); + assertEquals(l.size(), k); + } + } + + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ExchangerTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ExchangerTest.java new file mode 100755 index 0000000..9811e82 --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ExchangerTest.java @@ -0,0 +1,234 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.*; +import java.util.concurrent.*; + +public class ExchangerTest extends JSR166TestCase { + + public static void main(String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(ExchangerTest.class); + } + + /** + * exchange exchanges objects across two threads + */ + public void testExchange() { + final Exchanger e = new Exchanger(); + Thread t1 = new Thread(new Runnable(){ + public void run(){ + try { + Object v = e.exchange(one); + threadAssertEquals(v, two); + Object w = e.exchange(v); + threadAssertEquals(w, one); + } catch(InterruptedException e){ + threadUnexpectedException(); + } + } + }); + Thread t2 = new Thread(new Runnable(){ + public void run(){ + try { + Object v = e.exchange(two); + threadAssertEquals(v, one); + Object w = e.exchange(v); + threadAssertEquals(w, two); + } catch(InterruptedException e){ + threadUnexpectedException(); + } + } + }); + try { + t1.start(); + t2.start(); + t1.join(); + t2.join(); + } catch(InterruptedException ex) { + unexpectedException(); + } + } + + /** + * timed exchange exchanges objects across two threads + */ + public void testTimedExchange() { + final Exchanger e = new Exchanger(); + Thread t1 = new Thread(new Runnable(){ + public void run(){ + try { + Object v = e.exchange(one, SHORT_DELAY_MS, TimeUnit.MILLISECONDS); + threadAssertEquals(v, two); + Object w = e.exchange(v, SHORT_DELAY_MS, TimeUnit.MILLISECONDS); + threadAssertEquals(w, one); + } catch(InterruptedException e){ + threadUnexpectedException(); + } catch(TimeoutException toe) { + threadUnexpectedException(); + } + } + }); + Thread t2 = new Thread(new Runnable(){ + public void run(){ + try { + Object v = e.exchange(two, SHORT_DELAY_MS, TimeUnit.MILLISECONDS); + threadAssertEquals(v, one); + Object w = e.exchange(v, SHORT_DELAY_MS, TimeUnit.MILLISECONDS); + threadAssertEquals(w, two); + } catch(InterruptedException e){ + threadUnexpectedException(); + } catch(TimeoutException toe) { + threadUnexpectedException(); + } + } + }); + try { + t1.start(); + t2.start(); + t1.join(); + t2.join(); + } catch(InterruptedException ex) { + unexpectedException(); + } + } + + /** + * interrupt during wait for exchange throws IE + */ + public void testExchange_InterruptedException(){ + final Exchanger e = new Exchanger(); + Thread t = new Thread(new Runnable() { + public void run(){ + try { + e.exchange(one); + threadShouldThrow(); + } catch(InterruptedException success){ + } + } + }); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } catch(InterruptedException ex) { + unexpectedException(); + } + } + + /** + * interrupt during wait for timed exchange throws IE + */ + public void testTimedExchange_InterruptedException(){ + final Exchanger e = new Exchanger(); + Thread t = new Thread(new Runnable() { + public void run(){ + try { + e.exchange(null, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + threadShouldThrow(); + } catch(InterruptedException success){ + } catch(Exception e2){ + threadFail("should throw IE"); + } + } + }); + try { + t.start(); + t.interrupt(); + t.join(); + } catch(InterruptedException ex){ + unexpectedException(); + } + } + + /** + * timeout during wait for timed exchange throws TOE + */ + public void testExchange_TimeOutException(){ + final Exchanger e = new Exchanger(); + Thread t = new Thread(new Runnable() { + public void run(){ + try { + e.exchange(null, SHORT_DELAY_MS, TimeUnit.MILLISECONDS); + threadShouldThrow(); + } catch(TimeoutException success){ + } catch(InterruptedException e2){ + threadFail("should throw TOE"); + } + } + }); + try { + t.start(); + t.join(); + } catch(InterruptedException ex){ + unexpectedException(); + } + } + + /** + * If one exchanging thread is interrupted, another succeeds. + */ + public void testReplacementAfterExchange() { + final Exchanger e = new Exchanger(); + Thread t1 = new Thread(new Runnable(){ + public void run(){ + try { + Object v = e.exchange(one); + threadAssertEquals(v, two); + Object w = e.exchange(v); + threadShouldThrow(); + } catch(InterruptedException success){ + } + } + }); + Thread t2 = new Thread(new Runnable(){ + public void run(){ + try { + Object v = e.exchange(two); + threadAssertEquals(v, one); + Thread.sleep(SMALL_DELAY_MS); + Object w = e.exchange(v); + threadAssertEquals(w, three); + } catch(InterruptedException e){ + threadUnexpectedException(); + } + } + }); + Thread t3 = new Thread(new Runnable(){ + public void run(){ + try { + Thread.sleep(SMALL_DELAY_MS); + Object w = e.exchange(three); + threadAssertEquals(w, one); + } catch(InterruptedException e){ + threadUnexpectedException(); + } + } + }); + + try { + t1.start(); + t2.start(); + t3.start(); + Thread.sleep(SHORT_DELAY_MS); + t1.interrupt(); + t1.join(); + t2.join(); + t3.join(); + } catch(InterruptedException ex) { + unexpectedException(); + } + } + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ExecutorCompletionServiceTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ExecutorCompletionServiceTest.java new file mode 100644 index 0000000..2e237e2 --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ExecutorCompletionServiceTest.java @@ -0,0 +1,162 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.*; +import java.util.concurrent.*; +import java.math.BigInteger; +import java.security.*; + +public class ExecutorCompletionServiceTest extends JSR166TestCase{ + public static void main(String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(ExecutorCompletionServiceTest.class); + } + + + /** + * Creating a new ECS with null Executor throw NPE + */ + public void testConstructorNPE() { + try { + ExecutorCompletionService ecs = new ExecutorCompletionService(null); + shouldThrow(); + } catch (NullPointerException success) { + } + } + + /** + * Creating a new ECS with null queue throw NPE + */ + public void testConstructorNPE2() { + try { + ExecutorService e = Executors.newCachedThreadPool(); + ExecutorCompletionService ecs = new ExecutorCompletionService(e, null); + shouldThrow(); + } catch (NullPointerException success) { + } + } + + /** + * Submitting a null callable throws NPE + */ + public void testSubmitNPE() { + ExecutorService e = Executors.newCachedThreadPool(); + ExecutorCompletionService ecs = new ExecutorCompletionService(e); + try { + Callable c = null; + ecs.submit(c); + shouldThrow(); + } catch (NullPointerException success) { + } finally { + joinPool(e); + } + } + + /** + * Submitting a null runnable throws NPE + */ + public void testSubmitNPE2() { + ExecutorService e = Executors.newCachedThreadPool(); + ExecutorCompletionService ecs = new ExecutorCompletionService(e); + try { + Runnable r = null; + ecs.submit(r, Boolean.TRUE); + shouldThrow(); + } catch (NullPointerException success) { + } finally { + joinPool(e); + } + } + + /** + * A taken submitted task is completed + */ + public void testTake() { + ExecutorService e = Executors.newCachedThreadPool(); + ExecutorCompletionService ecs = new ExecutorCompletionService(e); + try { + Callable c = new StringTask(); + ecs.submit(c); + Future f = ecs.take(); + assert(f.isDone()); + } catch (Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * Take returns the same future object returned by submit + */ + public void testTake2() { + ExecutorService e = Executors.newCachedThreadPool(); + ExecutorCompletionService ecs = new ExecutorCompletionService(e); + try { + Callable c = new StringTask(); + Future f1 = ecs.submit(c); + Future f2 = ecs.take(); + assertSame(f1, f2); + } catch (Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * If poll returns non-null, the returned task is completed + */ + public void testPoll1() { + ExecutorService e = Executors.newCachedThreadPool(); + ExecutorCompletionService ecs = new ExecutorCompletionService(e); + try { + assertNull(ecs.poll()); + Callable c = new StringTask(); + ecs.submit(c); + Thread.sleep(SHORT_DELAY_MS); + for (;;) { + Future f = ecs.poll(); + if (f != null) { + assert(f.isDone()); + break; + } + } + } catch (Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * If timed poll returns non-null, the returned task is completed + */ + public void testPoll2() { + ExecutorService e = Executors.newCachedThreadPool(); + ExecutorCompletionService ecs = new ExecutorCompletionService(e); + try { + assertNull(ecs.poll()); + Callable c = new StringTask(); + ecs.submit(c); + Future f = ecs.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS); + if (f != null) + assert(f.isDone()); + } catch (Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ExecutorsTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ExecutorsTest.java new file mode 100755 index 0000000..40e23e4 --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ExecutorsTest.java @@ -0,0 +1,666 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.*; +import java.util.concurrent.*; +import java.math.BigInteger; +import java.security.*; + +public class ExecutorsTest extends JSR166TestCase{ + public static void main(String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(ExecutorsTest.class); + } + + static class TimedCallable<T> implements Callable<T> { + private final ExecutorService exec; + private final Callable<T> func; + private final long msecs; + + TimedCallable(ExecutorService exec, Callable<T> func, long msecs) { + this.exec = exec; + this.func = func; + this.msecs = msecs; + } + + public T call() throws Exception { + Future<T> ftask = exec.submit(func); + try { + return ftask.get(msecs, TimeUnit.MILLISECONDS); + } finally { + ftask.cancel(true); + } + } + } + + + private static class Fib implements Callable<BigInteger> { + private final BigInteger n; + Fib(long n) { + if (n < 0) throw new IllegalArgumentException("need non-negative arg, but got " + n); + this.n = BigInteger.valueOf(n); + } + public BigInteger call() { + BigInteger f1 = BigInteger.ONE; + BigInteger f2 = f1; + for (BigInteger i = BigInteger.ZERO; i.compareTo(n) < 0; i = i.add(BigInteger.ONE)) { + BigInteger t = f1.add(f2); + f1 = f2; + f2 = t; + } + return f1; + } + }; + + /** + * A newCachedThreadPool can execute runnables + */ + public void testNewCachedThreadPool1() { + ExecutorService e = Executors.newCachedThreadPool(); + e.execute(new NoOpRunnable()); + e.execute(new NoOpRunnable()); + e.execute(new NoOpRunnable()); + joinPool(e); + } + + /** + * A newCachedThreadPool with given ThreadFactory can execute runnables + */ + public void testNewCachedThreadPool2() { + ExecutorService e = Executors.newCachedThreadPool(new SimpleThreadFactory()); + e.execute(new NoOpRunnable()); + e.execute(new NoOpRunnable()); + e.execute(new NoOpRunnable()); + joinPool(e); + } + + /** + * A newCachedThreadPool with null ThreadFactory throws NPE + */ + public void testNewCachedThreadPool3() { + try { + ExecutorService e = Executors.newCachedThreadPool(null); + shouldThrow(); + } + catch(NullPointerException success) { + } + } + + + /** + * A new SingleThreadExecutor can execute runnables + */ + public void testNewSingleThreadExecutor1() { + ExecutorService e = Executors.newSingleThreadExecutor(); + e.execute(new NoOpRunnable()); + e.execute(new NoOpRunnable()); + e.execute(new NoOpRunnable()); + joinPool(e); + } + + /** + * A new SingleThreadExecutor with given ThreadFactory can execute runnables + */ + public void testNewSingleThreadExecutor2() { + ExecutorService e = Executors.newSingleThreadExecutor(new SimpleThreadFactory()); + e.execute(new NoOpRunnable()); + e.execute(new NoOpRunnable()); + e.execute(new NoOpRunnable()); + joinPool(e); + } + + /** + * A new SingleThreadExecutor with null ThreadFactory throws NPE + */ + public void testNewSingleThreadExecutor3() { + try { + ExecutorService e = Executors.newSingleThreadExecutor(null); + shouldThrow(); + } + catch(NullPointerException success) { + } + } + + /** + * A new SingleThreadExecutor cannot be casted to concrete implementation + */ + public void testCastNewSingleThreadExecutor() { + ExecutorService e = Executors.newSingleThreadExecutor(); + try { + ThreadPoolExecutor tpe = (ThreadPoolExecutor)e; + } catch (ClassCastException success) { + } finally { + joinPool(e); + } + } + + + /** + * A new newFixedThreadPool can execute runnables + */ + public void testNewFixedThreadPool1() { + ExecutorService e = Executors.newFixedThreadPool(2); + e.execute(new NoOpRunnable()); + e.execute(new NoOpRunnable()); + e.execute(new NoOpRunnable()); + joinPool(e); + } + + /** + * A new newFixedThreadPool with given ThreadFactory can execute runnables + */ + public void testNewFixedThreadPool2() { + ExecutorService e = Executors.newFixedThreadPool(2, new SimpleThreadFactory()); + e.execute(new NoOpRunnable()); + e.execute(new NoOpRunnable()); + e.execute(new NoOpRunnable()); + joinPool(e); + } + + /** + * A new newFixedThreadPool with null ThreadFactory throws NPE + */ + public void testNewFixedThreadPool3() { + try { + ExecutorService e = Executors.newFixedThreadPool(2, null); + shouldThrow(); + } + catch(NullPointerException success) { + } + } + + /** + * A new newFixedThreadPool with 0 threads throws IAE + */ + public void testNewFixedThreadPool4() { + try { + ExecutorService e = Executors.newFixedThreadPool(0); + shouldThrow(); + } + catch(IllegalArgumentException success) { + } + } + + + /** + * An unconfigurable newFixedThreadPool can execute runnables + */ + public void testunconfigurableExecutorService() { + ExecutorService e = Executors.unconfigurableExecutorService(Executors.newFixedThreadPool(2)); + e.execute(new NoOpRunnable()); + e.execute(new NoOpRunnable()); + e.execute(new NoOpRunnable()); + joinPool(e); + } + + /** + * unconfigurableExecutorService(null) throws NPE + */ + public void testunconfigurableExecutorServiceNPE() { + try { + ExecutorService e = Executors.unconfigurableExecutorService(null); + } + catch (NullPointerException success) { + } + } + + /** + * unconfigurableScheduledExecutorService(null) throws NPE + */ + public void testunconfigurableScheduledExecutorServiceNPE() { + try { + ExecutorService e = Executors.unconfigurableScheduledExecutorService(null); + } + catch (NullPointerException success) { + } + } + + + /** + * a newSingleThreadScheduledExecutor successfully runs delayed task + */ + public void testNewSingleThreadScheduledExecutor() { + try { + TrackedCallable callable = new TrackedCallable(); + ScheduledExecutorService p1 = Executors.newSingleThreadScheduledExecutor(); + Future f = p1.schedule(callable, SHORT_DELAY_MS, TimeUnit.MILLISECONDS); + assertFalse(callable.done); + Thread.sleep(MEDIUM_DELAY_MS); + assertTrue(callable.done); + assertEquals(Boolean.TRUE, f.get()); + joinPool(p1); + } catch(RejectedExecutionException e){} + catch(Exception e){ + e.printStackTrace(); + unexpectedException(); + } + } + + /** + * a newScheduledThreadPool successfully runs delayed task + */ + public void testnewScheduledThreadPool() { + try { + TrackedCallable callable = new TrackedCallable(); + ScheduledExecutorService p1 = Executors.newScheduledThreadPool(2); + Future f = p1.schedule(callable, SHORT_DELAY_MS, TimeUnit.MILLISECONDS); + assertFalse(callable.done); + Thread.sleep(MEDIUM_DELAY_MS); + assertTrue(callable.done); + assertEquals(Boolean.TRUE, f.get()); + joinPool(p1); + } catch(RejectedExecutionException e){} + catch(Exception e){ + e.printStackTrace(); + unexpectedException(); + } + } + + /** + * an unconfigurable newScheduledThreadPool successfully runs delayed task + */ + public void testunconfigurableScheduledExecutorService() { + try { + TrackedCallable callable = new TrackedCallable(); + ScheduledExecutorService p1 = Executors.unconfigurableScheduledExecutorService(Executors.newScheduledThreadPool(2)); + Future f = p1.schedule(callable, SHORT_DELAY_MS, TimeUnit.MILLISECONDS); + assertFalse(callable.done); + Thread.sleep(MEDIUM_DELAY_MS); + assertTrue(callable.done); + assertEquals(Boolean.TRUE, f.get()); + joinPool(p1); + } catch(RejectedExecutionException e){} + catch(Exception e){ + e.printStackTrace(); + unexpectedException(); + } + } + + /** + * timeouts from execute will time out if they compute too long. + */ + public void testTimedCallable() { + int N = 10000; + ExecutorService executor = Executors.newSingleThreadExecutor(); + List<Callable<BigInteger>> tasks = new ArrayList<Callable<BigInteger>>(N); + try { + long startTime = System.currentTimeMillis(); + + long i = 0; + while (tasks.size() < N) { + tasks.add(new TimedCallable<BigInteger>(executor, new Fib(i), 1)); + i += 10; + } + + int iters = 0; + BigInteger sum = BigInteger.ZERO; + for (Iterator<Callable<BigInteger>> it = tasks.iterator(); it.hasNext();) { + try { + ++iters; + sum = sum.add(it.next().call()); + } + catch (TimeoutException success) { + assertTrue(iters > 0); + return; + } + catch (Exception e) { + unexpectedException(); + } + } + // if by chance we didn't ever time out, total time must be small + long elapsed = System.currentTimeMillis() - startTime; + assertTrue(elapsed < N); + } + finally { + joinPool(executor); + } + } + + + /** + * ThreadPoolExecutor using defaultThreadFactory has + * specified group, priority, daemon status, and name + */ + public void testDefaultThreadFactory() { + final ThreadGroup egroup = Thread.currentThread().getThreadGroup(); + Runnable r = new Runnable() { + public void run() { + try { + Thread current = Thread.currentThread(); + threadAssertTrue(!current.isDaemon()); + threadAssertTrue(current.getPriority() == Thread.NORM_PRIORITY); + ThreadGroup g = current.getThreadGroup(); + SecurityManager s = System.getSecurityManager(); + if (s != null) + threadAssertTrue(g == s.getThreadGroup()); + else + threadAssertTrue(g == egroup); + String name = current.getName(); + threadAssertTrue(name.endsWith("thread-1")); + } catch (SecurityException ok) { + // Also pass if not allowed to change setting + } + } + }; + ExecutorService e = Executors.newSingleThreadExecutor(Executors.defaultThreadFactory()); + + e.execute(r); + try { + e.shutdown(); + } catch(SecurityException ok) { + } + + try { + Thread.sleep(SHORT_DELAY_MS); + } catch (Exception eX) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * ThreadPoolExecutor using privilegedThreadFactory has + * specified group, priority, daemon status, name, + * access control context and context class loader + */ + public void testPrivilegedThreadFactory() { + Policy savedPolicy = null; + try { + savedPolicy = Policy.getPolicy(); + AdjustablePolicy policy = new AdjustablePolicy(); + policy.addPermission(new RuntimePermission("getContextClassLoader")); + policy.addPermission(new RuntimePermission("setContextClassLoader")); + Policy.setPolicy(policy); + } catch (AccessControlException ok) { + return; + } + final ThreadGroup egroup = Thread.currentThread().getThreadGroup(); + final ClassLoader thisccl = Thread.currentThread().getContextClassLoader(); + final AccessControlContext thisacc = AccessController.getContext(); + Runnable r = new Runnable() { + public void run() { + try { + Thread current = Thread.currentThread(); + threadAssertTrue(!current.isDaemon()); + threadAssertTrue(current.getPriority() == Thread.NORM_PRIORITY); + ThreadGroup g = current.getThreadGroup(); + SecurityManager s = System.getSecurityManager(); + if (s != null) + threadAssertTrue(g == s.getThreadGroup()); + else + threadAssertTrue(g == egroup); + String name = current.getName(); + threadAssertTrue(name.endsWith("thread-1")); + threadAssertTrue(thisccl == current.getContextClassLoader()); + threadAssertTrue(thisacc.equals(AccessController.getContext())); + } catch(SecurityException ok) { + // Also pass if not allowed to change settings + } + } + }; + ExecutorService e = Executors.newSingleThreadExecutor(Executors.privilegedThreadFactory()); + + Policy.setPolicy(savedPolicy); + e.execute(r); + try { + e.shutdown(); + } catch(SecurityException ok) { + } + try { + Thread.sleep(SHORT_DELAY_MS); + } catch (Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + + } + + void checkCCL() { + AccessController.getContext().checkPermission(new RuntimePermission("getContextClassLoader")); + } + + class CheckCCL implements Callable<Object> { + public Object call() { + checkCCL(); + return null; + } + } + + + /** + * Without class loader permissions, creating + * privilegedCallableUsingCurrentClassLoader throws ACE + */ + public void testCreatePrivilegedCallableUsingCCLWithNoPrivs() { + Policy savedPolicy = null; + try { + savedPolicy = Policy.getPolicy(); + AdjustablePolicy policy = new AdjustablePolicy(); + Policy.setPolicy(policy); + } catch (AccessControlException ok) { + return; + } + + // Check if program still has too many permissions to run test + try { + checkCCL(); + // too many privileges to test; so return + Policy.setPolicy(savedPolicy); + return; + } catch(AccessControlException ok) { + } + + try { + Callable task = Executors.privilegedCallableUsingCurrentClassLoader(new NoOpCallable()); + shouldThrow(); + } catch(AccessControlException success) { + } catch(Exception ex) { + unexpectedException(); + } + finally { + Policy.setPolicy(savedPolicy); + } + } + + /** + * With class loader permissions, calling + * privilegedCallableUsingCurrentClassLoader does not throw ACE + */ + public void testprivilegedCallableUsingCCLWithPrivs() { + Policy savedPolicy = null; + try { + savedPolicy = Policy.getPolicy(); + AdjustablePolicy policy = new AdjustablePolicy(); + policy.addPermission(new RuntimePermission("getContextClassLoader")); + policy.addPermission(new RuntimePermission("setContextClassLoader")); + Policy.setPolicy(policy); + } catch (AccessControlException ok) { + return; + } + + try { + Callable task = Executors.privilegedCallableUsingCurrentClassLoader(new NoOpCallable()); + task.call(); + } catch(Exception ex) { + unexpectedException(); + } + finally { + Policy.setPolicy(savedPolicy); + } + } + + /** + * Without permissions, calling privilegedCallable throws ACE + */ + public void testprivilegedCallableWithNoPrivs() { + Callable task; + Policy savedPolicy = null; + AdjustablePolicy policy = null; + AccessControlContext noprivAcc = null; + try { + savedPolicy = Policy.getPolicy(); + policy = new AdjustablePolicy(); + Policy.setPolicy(policy); + noprivAcc = AccessController.getContext(); + task = Executors.privilegedCallable(new CheckCCL()); + Policy.setPolicy(savedPolicy); + } catch (AccessControlException ok) { + return; // program has too few permissions to set up test + } + + // Make sure that program doesn't have too many permissions + try { + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + checkCCL(); + return null; + }}, noprivAcc); + // too many permssions; skip test + return; + } catch(AccessControlException ok) { + } + + try { + task.call(); + shouldThrow(); + } catch(AccessControlException success) { + } catch(Exception ex) { + unexpectedException(); + } + } + + /** + * With permissions, calling privilegedCallable succeeds + */ + public void testprivilegedCallableWithPrivs() { + Policy savedPolicy = null; + try { + savedPolicy = Policy.getPolicy(); + AdjustablePolicy policy = new AdjustablePolicy(); + policy.addPermission(new RuntimePermission("getContextClassLoader")); + policy.addPermission(new RuntimePermission("setContextClassLoader")); + Policy.setPolicy(policy); + } catch (AccessControlException ok) { + return; + } + + Callable task = Executors.privilegedCallable(new CheckCCL()); + try { + task.call(); + } catch(Exception ex) { + unexpectedException(); + } finally { + Policy.setPolicy(savedPolicy); + } + } + + /** + * callable(Runnable) returns null when called + */ + public void testCallable1() { + try { + Callable c = Executors.callable(new NoOpRunnable()); + assertNull(c.call()); + } catch(Exception ex) { + unexpectedException(); + } + + } + + /** + * callable(Runnable, result) returns result when called + */ + public void testCallable2() { + try { + Callable c = Executors.callable(new NoOpRunnable(), one); + assertEquals(one, c.call()); + } catch(Exception ex) { + unexpectedException(); + } + } + + /** + * callable(PrivilegedAction) returns its result when called + */ + public void testCallable3() { + try { + Callable c = Executors.callable(new PrivilegedAction() { + public Object run() { return one; }}); + assertEquals(one, c.call()); + } catch(Exception ex) { + unexpectedException(); + } + } + + /** + * callable(PrivilegedExceptionAction) returns its result when called + */ + public void testCallable4() { + try { + Callable c = Executors.callable(new PrivilegedExceptionAction() { + public Object run() { return one; }}); + assertEquals(one, c.call()); + } catch(Exception ex) { + unexpectedException(); + } + } + + + /** + * callable(null Runnable) throws NPE + */ + public void testCallableNPE1() { + try { + Runnable r = null; + Callable c = Executors.callable(r); + } catch (NullPointerException success) { + } + } + + /** + * callable(null, result) throws NPE + */ + public void testCallableNPE2() { + try { + Runnable r = null; + Callable c = Executors.callable(r, one); + } catch (NullPointerException success) { + } + } + + /** + * callable(null PrivilegedAction) throws NPE + */ + public void testCallableNPE3() { + try { + PrivilegedAction r = null; + Callable c = Executors.callable(r); + } catch (NullPointerException success) { + } + } + + /** + * callable(null PrivilegedExceptionAction) throws NPE + */ + public void testCallableNPE4() { + try { + PrivilegedExceptionAction r = null; + Callable c = Executors.callable(r); + } catch (NullPointerException success) { + } + } + + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/FutureTaskTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/FutureTaskTest.java new file mode 100755 index 0000000..2108986 --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/FutureTaskTest.java @@ -0,0 +1,476 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.concurrent.*; +import java.util.*; + +public class FutureTaskTest extends JSR166TestCase { + + public static void main(String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(FutureTaskTest.class); + } + + /** + * Subclass to expose protected methods + */ + static class PublicFutureTask extends FutureTask { + public PublicFutureTask(Callable r) { super(r); } + public boolean runAndReset() { return super.runAndReset(); } + public void set(Object x) { super.set(x); } + public void setException(Throwable t) { super.setException(t); } + } + + /** + * Creating a future with a null callable throws NPE + */ + public void testConstructor() { + try { + FutureTask task = new FutureTask(null); + shouldThrow(); + } + catch(NullPointerException success) { + } + } + + /** + * creating a future with null runnable fails + */ + public void testConstructor2() { + try { + FutureTask task = new FutureTask(null, Boolean.TRUE); + shouldThrow(); + } + catch(NullPointerException success) { + } + } + + /** + * isDone is true when a task completes + */ + public void testIsDone() { + FutureTask task = new FutureTask( new NoOpCallable()); + task.run(); + assertTrue(task.isDone()); + assertFalse(task.isCancelled()); + } + + /** + * runAndReset of a non-cancelled task succeeds + */ + public void testRunAndReset() { + PublicFutureTask task = new PublicFutureTask(new NoOpCallable()); + assertTrue(task.runAndReset()); + assertFalse(task.isDone()); + } + + /** + * runAndReset after cancellation fails + */ + public void testResetAfterCancel() { + PublicFutureTask task = new PublicFutureTask(new NoOpCallable()); + assertTrue(task.cancel(false)); + assertFalse(task.runAndReset()); + assertTrue(task.isDone()); + assertTrue(task.isCancelled()); + } + + + + /** + * setting value causes get to return it + */ + public void testSet() { + PublicFutureTask task = new PublicFutureTask(new NoOpCallable()); + task.set(one); + try { + assertEquals(task.get(), one); + } + catch(Exception e) { + unexpectedException(); + } + } + + /** + * setException causes get to throw ExecutionException + */ + public void testSetException() { + Exception nse = new NoSuchElementException(); + PublicFutureTask task = new PublicFutureTask(new NoOpCallable()); + task.setException(nse); + try { + Object x = task.get(); + shouldThrow(); + } + catch(ExecutionException ee) { + Throwable cause = ee.getCause(); + assertEquals(cause, nse); + } + catch(Exception e) { + unexpectedException(); + } + } + + /** + * Cancelling before running succeeds + */ + public void testCancelBeforeRun() { + FutureTask task = new FutureTask( new NoOpCallable()); + assertTrue(task.cancel(false)); + task.run(); + assertTrue(task.isDone()); + assertTrue(task.isCancelled()); + } + + /** + * Cancel(true) before run succeeds + */ + public void testCancelBeforeRun2() { + FutureTask task = new FutureTask( new NoOpCallable()); + assertTrue(task.cancel(true)); + task.run(); + assertTrue(task.isDone()); + assertTrue(task.isCancelled()); + } + + /** + * cancel of a completed task fails + */ + public void testCancelAfterRun() { + FutureTask task = new FutureTask( new NoOpCallable()); + task.run(); + assertFalse(task.cancel(false)); + assertTrue(task.isDone()); + assertFalse(task.isCancelled()); + } + + /** + * cancel(true) interrupts a running task + */ + public void testCancelInterrupt() { + FutureTask task = new FutureTask( new Callable() { + public Object call() { + try { + Thread.sleep(MEDIUM_DELAY_MS); + threadShouldThrow(); + } + catch (InterruptedException success) {} + return Boolean.TRUE; + } }); + Thread t = new Thread(task); + t.start(); + + try { + Thread.sleep(SHORT_DELAY_MS); + assertTrue(task.cancel(true)); + t.join(); + assertTrue(task.isDone()); + assertTrue(task.isCancelled()); + } catch(InterruptedException e){ + unexpectedException(); + } + } + + + /** + * cancel(false) does not interrupt a running task + */ + public void testCancelNoInterrupt() { + FutureTask task = new FutureTask( new Callable() { + public Object call() { + try { + Thread.sleep(MEDIUM_DELAY_MS); + } + catch (InterruptedException success) { + threadFail("should not interrupt"); + } + return Boolean.TRUE; + } }); + Thread t = new Thread(task); + t.start(); + + try { + Thread.sleep(SHORT_DELAY_MS); + assertTrue(task.cancel(false)); + t.join(); + assertTrue(task.isDone()); + assertTrue(task.isCancelled()); + } catch(InterruptedException e){ + unexpectedException(); + } + } + + /** + * set in one thread causes get in another thread to retrieve value + */ + public void testGet1() { + final FutureTask ft = new FutureTask(new Callable() { + public Object call() { + try { + Thread.sleep(MEDIUM_DELAY_MS); + } catch(InterruptedException e){ + threadUnexpectedException(); + } + return Boolean.TRUE; + } + }); + Thread t = new Thread(new Runnable() { + public void run() { + try { + ft.get(); + } catch(Exception e){ + threadUnexpectedException(); + } + } + }); + try { + assertFalse(ft.isDone()); + assertFalse(ft.isCancelled()); + t.start(); + Thread.sleep(SHORT_DELAY_MS); + ft.run(); + t.join(); + assertTrue(ft.isDone()); + assertFalse(ft.isCancelled()); + } catch(InterruptedException e){ + unexpectedException(); + + } + } + + /** + * set in one thread causes timed get in another thread to retrieve value + */ + public void testTimedGet1() { + final FutureTask ft = new FutureTask(new Callable() { + public Object call() { + try { + Thread.sleep(MEDIUM_DELAY_MS); + } catch(InterruptedException e){ + threadUnexpectedException(); + } + return Boolean.TRUE; + } + }); + Thread t = new Thread(new Runnable() { + public void run() { + try { + ft.get(SHORT_DELAY_MS, TimeUnit.MILLISECONDS); + } catch(TimeoutException success) { + } catch(Exception e){ + threadUnexpectedException(); + } + } + }); + try { + assertFalse(ft.isDone()); + assertFalse(ft.isCancelled()); + t.start(); + ft.run(); + t.join(); + assertTrue(ft.isDone()); + assertFalse(ft.isCancelled()); + } catch(InterruptedException e){ + unexpectedException(); + + } + } + + /** + * Cancelling a task causes timed get in another thread to throw CancellationException + */ + public void testTimedGet_Cancellation() { + final FutureTask ft = new FutureTask(new Callable() { + public Object call() { + try { + Thread.sleep(SMALL_DELAY_MS); + threadShouldThrow(); + } catch(InterruptedException e) { + } + return Boolean.TRUE; + } + }); + try { + Thread t1 = new Thread(new Runnable() { + public void run() { + try { + ft.get(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + threadShouldThrow(); + } catch(CancellationException success) {} + catch(Exception e){ + threadUnexpectedException(); + } + } + }); + Thread t2 = new Thread(ft); + t1.start(); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + ft.cancel(true); + t1.join(); + t2.join(); + } catch(InterruptedException ie){ + unexpectedException(); + } + } + + /** + * Cancelling a task causes get in another thread to throw CancellationException + */ + public void testGet_Cancellation() { + final FutureTask ft = new FutureTask(new Callable() { + public Object call() { + try { + Thread.sleep(MEDIUM_DELAY_MS); + threadShouldThrow(); + } catch(InterruptedException e){ + } + return Boolean.TRUE; + } + }); + try { + Thread t1 = new Thread(new Runnable() { + public void run() { + try { + ft.get(); + threadShouldThrow(); + } catch(CancellationException success){ + } + catch(Exception e){ + threadUnexpectedException(); + } + } + }); + Thread t2 = new Thread(ft); + t1.start(); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + ft.cancel(true); + t1.join(); + t2.join(); + } catch(InterruptedException success){ + unexpectedException(); + } + } + + + /** + * A runtime exception in task causes get to throw ExecutionException + */ + public void testGet_ExecutionException() { + final FutureTask ft = new FutureTask(new Callable() { + public Object call() { + int i = 5/0; + return Boolean.TRUE; + } + }); + try { + ft.run(); + ft.get(); + shouldThrow(); + } catch(ExecutionException success){ + } + catch(Exception e){ + unexpectedException(); + } + } + + /** + * A runtime exception in task causes timed get to throw ExecutionException + */ + public void testTimedGet_ExecutionException2() { + final FutureTask ft = new FutureTask(new Callable() { + public Object call() { + int i = 5/0; + return Boolean.TRUE; + } + }); + try { + ft.run(); + ft.get(SHORT_DELAY_MS, TimeUnit.MILLISECONDS); + shouldThrow(); + } catch(ExecutionException success) { + } catch(TimeoutException success) { } // unlikely but OK + catch(Exception e){ + unexpectedException(); + } + } + + + /** + * Interrupting a waiting get causes it to throw InterruptedException + */ + public void testGet_InterruptedException() { + final FutureTask ft = new FutureTask(new NoOpCallable()); + Thread t = new Thread(new Runnable() { + public void run() { + try { + ft.get(); + threadShouldThrow(); + } catch(InterruptedException success){ + } catch(Exception e){ + threadUnexpectedException(); + } + } + }); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * Interrupting a waiting timed get causes it to throw InterruptedException + */ + public void testTimedGet_InterruptedException2() { + final FutureTask ft = new FutureTask(new NoOpCallable()); + Thread t = new Thread(new Runnable() { + public void run() { + try { + ft.get(LONG_DELAY_MS,TimeUnit.MILLISECONDS); + threadShouldThrow(); + } catch(InterruptedException success){} + catch(Exception e){ + threadUnexpectedException(); + } + } + }); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * A timed out timed get throws TimeoutException + */ + public void testGet_TimeoutException() { + try { + FutureTask ft = new FutureTask(new NoOpCallable()); + ft.get(1,TimeUnit.MILLISECONDS); + shouldThrow(); + } catch(TimeoutException success){} + catch(Exception success){ + unexpectedException(); + } + } + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/JSR166TestCase.java b/concurrent/src/test/java/tests/api/java/util/concurrent/JSR166TestCase.java new file mode 100644 index 0000000..70dafbc --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/JSR166TestCase.java @@ -0,0 +1,565 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.*; +import java.util.concurrent.*; +import java.io.*; +import java.security.*; + +/** + * Base class for JSR166 Junit TCK tests. Defines some constants, + * utility methods and classes, as well as a simple framework for + * helping to make sure that assertions failing in generated threads + * cause the associated test that generated them to itself fail (which + * JUnit doe not otherwise arrange). The rules for creating such + * tests are: + * + * <ol> + * + * <li> All assertions in code running in generated threads must use + * the forms {@link #threadFail} , {@link #threadAssertTrue} {@link + * #threadAssertEquals}, or {@link #threadAssertNull}, (not + * <tt>fail</tt>, <tt>assertTrue</tt>, etc.) It is OK (but not + * particularly recommended) for other code to use these forms too. + * Only the most typically used JUnit assertion methods are defined + * this way, but enough to live with.</li> + * + * <li> If you override {@link #setUp} or {@link #tearDown}, make sure + * to invoke <tt>super.setUp</tt> and <tt>super.tearDown</tt> within + * them. These methods are used to clear and check for thread + * assertion failures.</li> + * + * <li>All delays and timeouts must use one of the constants <tt> + * SHORT_DELAY_MS</tt>, <tt> SMALL_DELAY_MS</tt>, <tt> MEDIUM_DELAY_MS</tt>, + * <tt> LONG_DELAY_MS</tt>. The idea here is that a SHORT is always + * discriminable from zero time, and always allows enough time for the + * small amounts of computation (creating a thread, calling a few + * methods, etc) needed to reach a timeout point. Similarly, a SMALL + * is always discriminable as larger than SHORT and smaller than + * MEDIUM. And so on. These constants are set to conservative values, + * but even so, if there is ever any doubt, they can all be increased + * in one spot to rerun tests on slower platforms</li> + * + * <li> All threads generated must be joined inside each test case + * method (or <tt>fail</tt> to do so) before returning from the + * method. The <tt> joinPool</tt> method can be used to do this when + * using Executors.</li> + * + * </ol> + * + * <p> <b>Other notes</b> + * <ul> + * + * <li> Usually, there is one testcase method per JSR166 method + * covering "normal" operation, and then as many exception-testing + * methods as there are exceptions the method can throw. Sometimes + * there are multiple tests per JSR166 method when the different + * "normal" behaviors differ significantly. And sometimes testcases + * cover multiple methods when they cannot be tested in + * isolation.</li> + * + * <li> The documentation style for testcases is to provide as javadoc + * a simple sentence or two describing the property that the testcase + * method purports to test. The javadocs do not say anything about how + * the property is tested. To find out, read the code.</li> + * + * <li> These tests are "conformance tests", and do not attempt to + * test throughput, latency, scalability or other performance factors + * (see the separate "jtreg" tests for a set intended to check these + * for the most central aspects of functionality.) So, most tests use + * the smallest sensible numbers of threads, collection sizes, etc + * needed to check basic conformance.</li> + * + * <li>The test classes currently do not declare inclusion in + * any particular package to simplify things for people integrating + * them in TCK test suites.</li> + * + * <li> As a convenience, the <tt>main</tt> of this class (JSR166TestCase) + * runs all JSR166 unit tests.</li> + * + * </ul> + */ +public class JSR166TestCase extends TestCase { + /** + * Runs all JSR166 unit tests using junit.textui.TestRunner + */ + public static void main (String[] args) { + int iters = 1; + if (args.length > 0) + iters = Integer.parseInt(args[0]); + Test s = suite(); + for (int i = 0; i < iters; ++i) { + junit.textui.TestRunner.run (s); + System.gc(); + System.runFinalization(); + } + System.exit(0); + } + + /** + * Collects all JSR166 unit tests as one suite + */ + public static Test suite ( ) { + TestSuite suite = tests.TestSuiteFactory.createTestSuite("JSR166 Unit Tests"); + // BEGIN android-changed + suite.addTest(AbstractExecutorServiceTest.suite()); + suite.addTest(AbstractQueueTest.suite()); + suite.addTest(AbstractQueuedSynchronizerTest.suite()); + suite.addTest(ArrayBlockingQueueTest.suite()); + suite.addTest(AtomicBooleanTest.suite()); + suite.addTest(AtomicIntegerArrayTest.suite()); + suite.addTest(AtomicIntegerFieldUpdaterTest.suite()); + suite.addTest(AtomicIntegerTest.suite()); + suite.addTest(AtomicLongArrayTest.suite()); + suite.addTest(AtomicLongFieldUpdaterTest.suite()); + suite.addTest(AtomicLongTest.suite()); + suite.addTest(AtomicMarkableReferenceTest.suite()); + suite.addTest(AtomicReferenceArrayTest.suite()); + suite.addTest(AtomicReferenceFieldUpdaterTest.suite()); + suite.addTest(AtomicReferenceTest.suite()); + suite.addTest(AtomicStampedReferenceTest.suite()); + suite.addTest(ConcurrentHashMapTest.suite()); + suite.addTest(ConcurrentLinkedQueueTest.suite()); + suite.addTest(CopyOnWriteArrayListTest.suite()); + suite.addTest(CopyOnWriteArraySetTest.suite()); + suite.addTest(CountDownLatchTest.suite()); + suite.addTest(CyclicBarrierTest.suite()); + suite.addTest(DelayQueueTest.suite()); + suite.addTest(ExchangerTest.suite()); + suite.addTest(ExecutorsTest.suite()); + suite.addTest(ExecutorCompletionServiceTest.suite()); + suite.addTest(FutureTaskTest.suite()); + suite.addTest(LinkedBlockingQueueTest.suite()); + suite.addTest(LinkedListTest.suite()); + suite.addTest(LockSupportTest.suite()); + suite.addTest(PriorityBlockingQueueTest.suite()); + suite.addTest(PriorityQueueTest.suite()); + suite.addTest(ReentrantLockTest.suite()); + suite.addTest(ReentrantReadWriteLockTest.suite()); + suite.addTest(ScheduledExecutorTest.suite()); + suite.addTest(SemaphoreTest.suite()); + suite.addTest(SynchronousQueueTest.suite()); + suite.addTest(SystemTest.suite()); + suite.addTest(ThreadLocalTest.suite()); + suite.addTest(ThreadPoolExecutorTest.suite()); + suite.addTest(ThreadTest.suite()); + suite.addTest(TimeUnitTest.suite()); + // END android-changed + return suite; + } + + + public static long SHORT_DELAY_MS; + public static long SMALL_DELAY_MS; + public static long MEDIUM_DELAY_MS; + public static long LONG_DELAY_MS; + + + /** + * Return the shortest timed delay. This could + * be reimplemented to use for example a Property. + */ + protected long getShortDelay() { + return 50; + } + + + /** + * Set delays as multiples of SHORT_DELAY. + */ + protected void setDelays() { + SHORT_DELAY_MS = getShortDelay(); + SMALL_DELAY_MS = SHORT_DELAY_MS * 5; + MEDIUM_DELAY_MS = SHORT_DELAY_MS * 10; + LONG_DELAY_MS = SHORT_DELAY_MS * 50; + } + + /** + * Flag set true if any threadAssert methods fail + */ + volatile boolean threadFailed; + + /** + * Initialize test to indicate that no thread assertions have failed + */ + public void setUp() { + setDelays(); + threadFailed = false; + } + + /** + * Trigger test case failure if any thread assertions have failed + */ + public void tearDown() { + assertFalse(threadFailed); + } + + /** + * Fail, also setting status to indicate current testcase should fail + */ + public void threadFail(String reason) { + threadFailed = true; + fail(reason); + } + + /** + * If expression not true, set status to indicate current testcase + * should fail + */ + public void threadAssertTrue(boolean b) { + if (!b) { + threadFailed = true; + assertTrue(b); + } + } + + /** + * If expression not false, set status to indicate current testcase + * should fail + */ + public void threadAssertFalse(boolean b) { + if (b) { + threadFailed = true; + assertFalse(b); + } + } + + /** + * If argument not null, set status to indicate current testcase + * should fail + */ + public void threadAssertNull(Object x) { + if (x != null) { + threadFailed = true; + assertNull(x); + } + } + + /** + * If arguments not equal, set status to indicate current testcase + * should fail + */ + public void threadAssertEquals(long x, long y) { + if (x != y) { + threadFailed = true; + assertEquals(x, y); + } + } + + /** + * If arguments not equal, set status to indicate current testcase + * should fail + */ + public void threadAssertEquals(Object x, Object y) { + if (x != y && (x == null || !x.equals(y))) { + threadFailed = true; + assertEquals(x, y); + } + } + + /** + * threadFail with message "should throw exception" + */ + public void threadShouldThrow() { + threadFailed = true; + fail("should throw exception"); + } + + /** + * threadFail with message "Unexpected exception" + */ + public void threadUnexpectedException() { + threadFailed = true; + fail("Unexpected exception"); + } + + + /** + * Wait out termination of a thread pool or fail doing so + */ + public void joinPool(ExecutorService exec) { + try { + exec.shutdown(); + assertTrue(exec.awaitTermination(LONG_DELAY_MS, TimeUnit.MILLISECONDS)); + } catch(SecurityException ok) { + // Allowed in case test doesn't have privs + } catch(InterruptedException ie) { + fail("Unexpected exception"); + } + } + + + /** + * fail with message "should throw exception" + */ + public void shouldThrow() { + fail("Should throw exception"); + } + + /** + * fail with message "Unexpected exception" + */ + public void unexpectedException() { + fail("Unexpected exception"); + } + + + /** + * The number of elements to place in collections, arrays, etc. + */ + static final int SIZE = 20; + + // Some convenient Integer constants + + static final Integer zero = new Integer(0); + static final Integer one = new Integer(1); + static final Integer two = new Integer(2); + static final Integer three = new Integer(3); + static final Integer four = new Integer(4); + static final Integer five = new Integer(5); + static final Integer six = new Integer(6); + static final Integer seven = new Integer(7); + static final Integer eight = new Integer(8); + static final Integer nine = new Integer(9); + static final Integer m1 = new Integer(-1); + static final Integer m2 = new Integer(-2); + static final Integer m3 = new Integer(-3); + static final Integer m4 = new Integer(-4); + static final Integer m5 = new Integer(-5); + static final Integer m10 = new Integer(-10); + + + /** + * A security policy where new permissions can be dynamically added + * or all cleared. + */ + static class AdjustablePolicy extends java.security.Policy { + Permissions perms = new Permissions(); + AdjustablePolicy() { } + void addPermission(Permission perm) { perms.add(perm); } + void clearPermissions() { perms = new Permissions(); } + public PermissionCollection getPermissions(CodeSource cs) { + return perms; + } + public PermissionCollection getPermissions(ProtectionDomain pd) { + return perms; + } + public boolean implies(ProtectionDomain pd, Permission p) { + return perms.implies(p); + } + public void refresh() {} + } + + + // Some convenient Runnable classes + + static class NoOpRunnable implements Runnable { + public void run() {} + } + + static class NoOpCallable implements Callable { + public Object call() { return Boolean.TRUE; } + } + + static final String TEST_STRING = "a test string"; + + static class StringTask implements Callable<String> { + public String call() { return TEST_STRING; } + } + + static class NPETask implements Callable<String> { + public String call() { throw new NullPointerException(); } + } + + static class CallableOne implements Callable<Integer> { + public Integer call() { return one; } + } + + class ShortRunnable implements Runnable { + public void run() { + try { + Thread.sleep(SHORT_DELAY_MS); + } + catch(Exception e) { + threadUnexpectedException(); + } + } + } + + class ShortInterruptedRunnable implements Runnable { + public void run() { + try { + Thread.sleep(SHORT_DELAY_MS); + threadShouldThrow(); + } + catch(InterruptedException success) { + } + } + } + + class SmallRunnable implements Runnable { + public void run() { + try { + Thread.sleep(SMALL_DELAY_MS); + } + catch(Exception e) { + threadUnexpectedException(); + } + } + } + + class SmallPossiblyInterruptedRunnable implements Runnable { + public void run() { + try { + Thread.sleep(SMALL_DELAY_MS); + } + catch(Exception e) { + } + } + } + + class SmallCallable implements Callable { + public Object call() { + try { + Thread.sleep(SMALL_DELAY_MS); + } + catch(Exception e) { + threadUnexpectedException(); + } + return Boolean.TRUE; + } + } + + class SmallInterruptedRunnable implements Runnable { + public void run() { + try { + Thread.sleep(SMALL_DELAY_MS); + threadShouldThrow(); + } + catch(InterruptedException success) { + } + } + } + + + class MediumRunnable implements Runnable { + public void run() { + try { + Thread.sleep(MEDIUM_DELAY_MS); + } + catch(Exception e) { + threadUnexpectedException(); + } + } + } + + class MediumInterruptedRunnable implements Runnable { + public void run() { + try { + Thread.sleep(MEDIUM_DELAY_MS); + threadShouldThrow(); + } + catch(InterruptedException success) { + } + } + } + + class MediumPossiblyInterruptedRunnable implements Runnable { + public void run() { + try { + Thread.sleep(MEDIUM_DELAY_MS); + } + catch(InterruptedException success) { + } + } + } + + class LongPossiblyInterruptedRunnable implements Runnable { + public void run() { + try { + Thread.sleep(LONG_DELAY_MS); + } + catch(InterruptedException success) { + } + } + } + + /** + * For use as ThreadFactory in constructors + */ + static class SimpleThreadFactory implements ThreadFactory{ + public Thread newThread(Runnable r){ + return new Thread(r); + } + } + + static class TrackedShortRunnable implements Runnable { + volatile boolean done = false; + public void run() { + try { + Thread.sleep(SMALL_DELAY_MS); + done = true; + } catch(Exception e){ + } + } + } + + static class TrackedMediumRunnable implements Runnable { + volatile boolean done = false; + public void run() { + try { + Thread.sleep(MEDIUM_DELAY_MS); + done = true; + } catch(Exception e){ + } + } + } + + static class TrackedLongRunnable implements Runnable { + volatile boolean done = false; + public void run() { + try { + Thread.sleep(LONG_DELAY_MS); + done = true; + } catch(Exception e){ + } + } + } + + static class TrackedNoOpRunnable implements Runnable { + volatile boolean done = false; + public void run() { + done = true; + } + } + + static class TrackedCallable implements Callable { + volatile boolean done = false; + public Object call() { + try { + Thread.sleep(SMALL_DELAY_MS); + done = true; + } catch(Exception e){ + } + return Boolean.TRUE; + } + } + + + /** + * For use as RejectedExecutionHandler in constructors + */ + static class NoOpREHandler implements RejectedExecutionHandler{ + public void rejectedExecution(Runnable r, ThreadPoolExecutor executor){} + } + + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/LinkedBlockingQueueTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/LinkedBlockingQueueTest.java new file mode 100755 index 0000000..7496a4a --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/LinkedBlockingQueueTest.java @@ -0,0 +1,1031 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.*; +import java.util.concurrent.*; +import java.io.*; + +public class LinkedBlockingQueueTest extends JSR166TestCase { + + public static void main(String[] args) { + junit.textui.TestRunner.run (suite()); + } + + public static Test suite() { + return new TestSuite(LinkedBlockingQueueTest.class); + } + + + /** + * Create a queue of given size containing consecutive + * Integers 0 ... n. + */ + private LinkedBlockingQueue populatedQueue(int n) { + LinkedBlockingQueue q = new LinkedBlockingQueue(n); + assertTrue(q.isEmpty()); + for(int i = 0; i < n; i++) + assertTrue(q.offer(new Integer(i))); + assertFalse(q.isEmpty()); + assertEquals(0, q.remainingCapacity()); + assertEquals(n, q.size()); + return q; + } + + /** + * A new queue has the indicated capacity, or Integer.MAX_VALUE if + * none given + */ + public void testConstructor1() { + assertEquals(SIZE, new LinkedBlockingQueue(SIZE).remainingCapacity()); + assertEquals(Integer.MAX_VALUE, new LinkedBlockingQueue().remainingCapacity()); + } + + /** + * Constructor throws IAE if capacity argument nonpositive + */ + public void testConstructor2() { + try { + LinkedBlockingQueue q = new LinkedBlockingQueue(0); + shouldThrow(); + } + catch (IllegalArgumentException success) {} + } + + /** + * Initializing from null Collection throws NPE + */ + public void testConstructor3() { + try { + LinkedBlockingQueue q = new LinkedBlockingQueue(null); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * Initializing from Collection of null elements throws NPE + */ + public void testConstructor4() { + try { + Integer[] ints = new Integer[SIZE]; + LinkedBlockingQueue q = new LinkedBlockingQueue(Arrays.asList(ints)); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * Initializing from Collection with some null elements throws NPE + */ + public void testConstructor5() { + try { + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE-1; ++i) + ints[i] = new Integer(i); + LinkedBlockingQueue q = new LinkedBlockingQueue(Arrays.asList(ints)); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * Queue contains all elements of collection used to initialize + */ + public void testConstructor6() { + try { + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE; ++i) + ints[i] = new Integer(i); + LinkedBlockingQueue q = new LinkedBlockingQueue(Arrays.asList(ints)); + for (int i = 0; i < SIZE; ++i) + assertEquals(ints[i], q.poll()); + } + finally {} + } + + /** + * Queue transitions from empty to full when elements added + */ + public void testEmptyFull() { + LinkedBlockingQueue q = new LinkedBlockingQueue(2); + assertTrue(q.isEmpty()); + assertEquals("should have room for 2", 2, q.remainingCapacity()); + q.add(one); + assertFalse(q.isEmpty()); + q.add(two); + assertFalse(q.isEmpty()); + assertEquals(0, q.remainingCapacity()); + assertFalse(q.offer(three)); + } + + /** + * remainingCapacity decreases on add, increases on remove + */ + public void testRemainingCapacity() { + LinkedBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.remainingCapacity()); + assertEquals(SIZE-i, q.size()); + q.remove(); + } + for (int i = 0; i < SIZE; ++i) { + assertEquals(SIZE-i, q.remainingCapacity()); + assertEquals(i, q.size()); + q.add(new Integer(i)); + } + } + + /** + * offer(null) throws NPE + */ + public void testOfferNull() { + try { + LinkedBlockingQueue q = new LinkedBlockingQueue(1); + q.offer(null); + shouldThrow(); + } catch (NullPointerException success) { } + } + + /** + * add(null) throws NPE + */ + public void testAddNull() { + try { + LinkedBlockingQueue q = new LinkedBlockingQueue(1); + q.add(null); + shouldThrow(); + } catch (NullPointerException success) { } + } + + /** + * Offer succeeds if not full; fails if full + */ + public void testOffer() { + LinkedBlockingQueue q = new LinkedBlockingQueue(1); + assertTrue(q.offer(zero)); + assertFalse(q.offer(one)); + } + + /** + * add succeeds if not full; throws ISE if full + */ + public void testAdd() { + try { + LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertTrue(q.add(new Integer(i))); + } + assertEquals(0, q.remainingCapacity()); + q.add(new Integer(SIZE)); + } catch (IllegalStateException success){ + } + } + + /** + * addAll(null) throws NPE + */ + public void testAddAll1() { + try { + LinkedBlockingQueue q = new LinkedBlockingQueue(1); + q.addAll(null); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * addAll(this) throws IAE + */ + public void testAddAllSelf() { + try { + LinkedBlockingQueue q = populatedQueue(SIZE); + q.addAll(q); + shouldThrow(); + } + catch (IllegalArgumentException success) {} + } + + /** + * addAll of a collection with null elements throws NPE + */ + public void testAddAll2() { + try { + LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE); + Integer[] ints = new Integer[SIZE]; + q.addAll(Arrays.asList(ints)); + shouldThrow(); + } + catch (NullPointerException success) {} + } + /** + * addAll of a collection with any null elements throws NPE after + * possibly adding some elements + */ + public void testAddAll3() { + try { + LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE); + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE-1; ++i) + ints[i] = new Integer(i); + q.addAll(Arrays.asList(ints)); + shouldThrow(); + } + catch (NullPointerException success) {} + } + /** + * addAll throws ISE if not enough room + */ + public void testAddAll4() { + try { + LinkedBlockingQueue q = new LinkedBlockingQueue(1); + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE; ++i) + ints[i] = new Integer(i); + q.addAll(Arrays.asList(ints)); + shouldThrow(); + } + catch (IllegalStateException success) {} + } + /** + * Queue contains all elements, in traversal order, of successful addAll + */ + public void testAddAll5() { + try { + Integer[] empty = new Integer[0]; + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE; ++i) + ints[i] = new Integer(i); + LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE); + assertFalse(q.addAll(Arrays.asList(empty))); + assertTrue(q.addAll(Arrays.asList(ints))); + for (int i = 0; i < SIZE; ++i) + assertEquals(ints[i], q.poll()); + } + finally {} + } + + /** + * put(null) throws NPE + */ + public void testPutNull() { + try { + LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE); + q.put(null); + shouldThrow(); + } + catch (NullPointerException success){ + } + catch (InterruptedException ie) { + unexpectedException(); + } + } + + /** + * all elements successfully put are contained + */ + public void testPut() { + try { + LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + Integer I = new Integer(i); + q.put(I); + assertTrue(q.contains(I)); + } + assertEquals(0, q.remainingCapacity()); + } + catch (InterruptedException ie) { + unexpectedException(); + } + } + + /** + * put blocks interruptibly if full + */ + public void testBlockingPut() { + Thread t = new Thread(new Runnable() { + public void run() { + int added = 0; + try { + LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + q.put(new Integer(i)); + ++added; + } + q.put(new Integer(SIZE)); + threadShouldThrow(); + } catch (InterruptedException ie){ + threadAssertEquals(added, SIZE); + } + }}); + t.start(); + try { + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } + catch (InterruptedException ie) { + unexpectedException(); + } + } + + /** + * put blocks waiting for take when full + */ + public void testPutWithTake() { + final LinkedBlockingQueue q = new LinkedBlockingQueue(2); + Thread t = new Thread(new Runnable() { + public void run() { + int added = 0; + try { + q.put(new Object()); + ++added; + q.put(new Object()); + ++added; + q.put(new Object()); + ++added; + q.put(new Object()); + ++added; + threadShouldThrow(); + } catch (InterruptedException e){ + threadAssertTrue(added >= 2); + } + } + }); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + q.take(); + t.interrupt(); + t.join(); + } catch (Exception e){ + unexpectedException(); + } + } + + /** + * timed offer times out if full and elements not taken + */ + public void testTimedOffer() { + final LinkedBlockingQueue q = new LinkedBlockingQueue(2); + Thread t = new Thread(new Runnable() { + public void run() { + try { + q.put(new Object()); + q.put(new Object()); + threadAssertFalse(q.offer(new Object(), SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + q.offer(new Object(), LONG_DELAY_MS, TimeUnit.MILLISECONDS); + threadShouldThrow(); + } catch (InterruptedException success){} + } + }); + + try { + t.start(); + Thread.sleep(SMALL_DELAY_MS); + t.interrupt(); + t.join(); + } catch (Exception e){ + unexpectedException(); + } + } + + /** + * take retrieves elements in FIFO order + */ + public void testTake() { + try { + LinkedBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.take()).intValue()); + } + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * take blocks interruptibly when empty + */ + public void testTakeFromEmpty() { + final LinkedBlockingQueue q = new LinkedBlockingQueue(2); + Thread t = new Thread(new Runnable() { + public void run() { + try { + q.take(); + threadShouldThrow(); + } catch (InterruptedException success){ } + } + }); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } catch (Exception e){ + unexpectedException(); + } + } + + /** + * Take removes existing elements until empty, then blocks interruptibly + */ + public void testBlockingTake() { + Thread t = new Thread(new Runnable() { + public void run() { + try { + LinkedBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.take()).intValue()); + } + q.take(); + threadShouldThrow(); + } catch (InterruptedException success){ + } + }}); + t.start(); + try { + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } + catch (InterruptedException ie) { + unexpectedException(); + } + } + + + /** + * poll succeeds unless empty + */ + public void testPoll() { + LinkedBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.poll()).intValue()); + } + assertNull(q.poll()); + } + + /** + * timed pool with zero timeout succeeds when non-empty, else times out + */ + public void testTimedPoll0() { + try { + LinkedBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.poll(0, TimeUnit.MILLISECONDS)).intValue()); + } + assertNull(q.poll(0, TimeUnit.MILLISECONDS)); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * timed pool with nonzero timeout succeeds when non-empty, else times out + */ + public void testTimedPoll() { + try { + LinkedBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)).intValue()); + } + assertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * Interrupted timed poll throws InterruptedException instead of + * returning timeout status + */ + public void testInterruptedTimedPoll() { + Thread t = new Thread(new Runnable() { + public void run() { + try { + LinkedBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + threadAssertEquals(i, ((Integer)q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)).intValue()); + } + threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + } catch (InterruptedException success){ + } + }}); + t.start(); + try { + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } + catch (InterruptedException ie) { + unexpectedException(); + } + } + + /** + * timed poll before a delayed offer fails; after offer succeeds; + * on interruption throws + */ + public void testTimedPollWithOffer() { + final LinkedBlockingQueue q = new LinkedBlockingQueue(2); + Thread t = new Thread(new Runnable() { + public void run() { + try { + threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS); + q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS); + threadShouldThrow(); + } catch (InterruptedException success) { } + } + }); + try { + t.start(); + Thread.sleep(SMALL_DELAY_MS); + assertTrue(q.offer(zero, SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + t.interrupt(); + t.join(); + } catch (Exception e){ + unexpectedException(); + } + } + + /** + * peek returns next element, or null if empty + */ + public void testPeek() { + LinkedBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.peek()).intValue()); + q.poll(); + assertTrue(q.peek() == null || + i != ((Integer)q.peek()).intValue()); + } + assertNull(q.peek()); + } + + /** + * element returns next element, or throws NSEE if empty + */ + public void testElement() { + LinkedBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.element()).intValue()); + q.poll(); + } + try { + q.element(); + shouldThrow(); + } + catch (NoSuchElementException success) {} + } + + /** + * remove removes next element, or throws NSEE if empty + */ + public void testRemove() { + LinkedBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.remove()).intValue()); + } + try { + q.remove(); + shouldThrow(); + } catch (NoSuchElementException success){ + } + } + + /** + * remove(x) removes x and returns true if present + */ + public void testRemoveElement() { + LinkedBlockingQueue q = populatedQueue(SIZE); + for (int i = 1; i < SIZE; i+=2) { + assertTrue(q.remove(new Integer(i))); + } + for (int i = 0; i < SIZE; i+=2) { + assertTrue(q.remove(new Integer(i))); + assertFalse(q.remove(new Integer(i+1))); + } + assertTrue(q.isEmpty()); + } + + /** + * contains(x) reports true when elements added but not yet removed + */ + public void testContains() { + LinkedBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertTrue(q.contains(new Integer(i))); + q.poll(); + assertFalse(q.contains(new Integer(i))); + } + } + + /** + * clear removes all elements + */ + public void testClear() { + LinkedBlockingQueue q = populatedQueue(SIZE); + q.clear(); + assertTrue(q.isEmpty()); + assertEquals(0, q.size()); + assertEquals(SIZE, q.remainingCapacity()); + q.add(one); + assertFalse(q.isEmpty()); + q.clear(); + assertTrue(q.isEmpty()); + } + + /** + * containsAll(c) is true when c contains a subset of elements + */ + public void testContainsAll() { + LinkedBlockingQueue q = populatedQueue(SIZE); + LinkedBlockingQueue p = new LinkedBlockingQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertTrue(q.containsAll(p)); + assertFalse(p.containsAll(q)); + p.add(new Integer(i)); + } + assertTrue(p.containsAll(q)); + } + + /** + * retainAll(c) retains only those elements of c and reports true if changed + */ + public void testRetainAll() { + LinkedBlockingQueue q = populatedQueue(SIZE); + LinkedBlockingQueue p = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + boolean changed = q.retainAll(p); + if (i == 0) + assertFalse(changed); + else + assertTrue(changed); + + assertTrue(q.containsAll(p)); + assertEquals(SIZE-i, q.size()); + p.remove(); + } + } + + /** + * removeAll(c) removes only those elements of c and reports true if changed + */ + public void testRemoveAll() { + for (int i = 1; i < SIZE; ++i) { + LinkedBlockingQueue q = populatedQueue(SIZE); + LinkedBlockingQueue p = populatedQueue(i); + assertTrue(q.removeAll(p)); + assertEquals(SIZE-i, q.size()); + for (int j = 0; j < i; ++j) { + Integer I = (Integer)(p.remove()); + assertFalse(q.contains(I)); + } + } + } + + /** + * toArray contains all elements + */ + public void testToArray() { + LinkedBlockingQueue q = populatedQueue(SIZE); + Object[] o = q.toArray(); + try { + for(int i = 0; i < o.length; i++) + assertEquals(o[i], q.take()); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * toArray(a) contains all elements + */ + public void testToArray2() { + LinkedBlockingQueue q = populatedQueue(SIZE); + Integer[] ints = new Integer[SIZE]; + ints = (Integer[])q.toArray(ints); + try { + for(int i = 0; i < ints.length; i++) + assertEquals(ints[i], q.take()); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * toArray(null) throws NPE + */ + public void testToArray_BadArg() { + try { + LinkedBlockingQueue q = populatedQueue(SIZE); + Object o[] = q.toArray(null); + shouldThrow(); + } catch(NullPointerException success){} + } + + /** + * toArray with incompatible array type throws CCE + */ + public void testToArray1_BadArg() { + try { + LinkedBlockingQueue q = populatedQueue(SIZE); + Object o[] = q.toArray(new String[10] ); + shouldThrow(); + } catch(ArrayStoreException success){} + } + + + /** + * iterator iterates through all elements + */ + public void testIterator() { + LinkedBlockingQueue q = populatedQueue(SIZE); + Iterator it = q.iterator(); + try { + while(it.hasNext()){ + assertEquals(it.next(), q.take()); + } + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * iterator.remove removes current element + */ + public void testIteratorRemove () { + final LinkedBlockingQueue q = new LinkedBlockingQueue(3); + q.add(two); + q.add(one); + q.add(three); + + Iterator it = q.iterator(); + it.next(); + it.remove(); + + it = q.iterator(); + assertEquals(it.next(), one); + assertEquals(it.next(), three); + assertFalse(it.hasNext()); + } + + + /** + * iterator ordering is FIFO + */ + public void testIteratorOrdering() { + final LinkedBlockingQueue q = new LinkedBlockingQueue(3); + q.add(one); + q.add(two); + q.add(three); + assertEquals(0, q.remainingCapacity()); + int k = 0; + for (Iterator it = q.iterator(); it.hasNext();) { + int i = ((Integer)(it.next())).intValue(); + assertEquals(++k, i); + } + assertEquals(3, k); + } + + /** + * Modifications do not cause iterators to fail + */ + public void testWeaklyConsistentIteration () { + final LinkedBlockingQueue q = new LinkedBlockingQueue(3); + q.add(one); + q.add(two); + q.add(three); + try { + for (Iterator it = q.iterator(); it.hasNext();) { + q.remove(); + it.next(); + } + } + catch (ConcurrentModificationException e) { + unexpectedException(); + } + assertEquals(0, q.size()); + } + + + /** + * toString contains toStrings of elements + */ + public void testToString() { + LinkedBlockingQueue q = populatedQueue(SIZE); + String s = q.toString(); + for (int i = 0; i < SIZE; ++i) { + assertTrue(s.indexOf(String.valueOf(i)) >= 0); + } + } + + + /** + * offer transfers elements across Executor tasks + */ + public void testOfferInExecutor() { + final LinkedBlockingQueue q = new LinkedBlockingQueue(2); + q.add(one); + q.add(two); + ExecutorService executor = Executors.newFixedThreadPool(2); + executor.execute(new Runnable() { + public void run() { + threadAssertFalse(q.offer(three)); + try { + threadAssertTrue(q.offer(three, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS)); + threadAssertEquals(0, q.remainingCapacity()); + } + catch (InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + executor.execute(new Runnable() { + public void run() { + try { + Thread.sleep(SMALL_DELAY_MS); + threadAssertEquals(one, q.take()); + } + catch (InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + joinPool(executor); + } + + /** + * poll retrieves elements across Executor threads + */ + public void testPollInExecutor() { + final LinkedBlockingQueue q = new LinkedBlockingQueue(2); + ExecutorService executor = Executors.newFixedThreadPool(2); + executor.execute(new Runnable() { + public void run() { + threadAssertNull(q.poll()); + try { + threadAssertTrue(null != q.poll(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS)); + threadAssertTrue(q.isEmpty()); + } + catch (InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + executor.execute(new Runnable() { + public void run() { + try { + Thread.sleep(SMALL_DELAY_MS); + q.put(one); + } + catch (InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + joinPool(executor); + } + + /** + * A deserialized serialized queue has same elements in same order + */ + public void testSerialization() { + LinkedBlockingQueue q = populatedQueue(SIZE); + + try { + ByteArrayOutputStream bout = new ByteArrayOutputStream(10000); + ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout)); + out.writeObject(q); + out.close(); + + ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); + ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin)); + LinkedBlockingQueue r = (LinkedBlockingQueue)in.readObject(); + assertEquals(q.size(), r.size()); + while (!q.isEmpty()) + assertEquals(q.remove(), r.remove()); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * drainTo(null) throws NPE + */ + public void testDrainToNull() { + LinkedBlockingQueue q = populatedQueue(SIZE); + try { + q.drainTo(null); + shouldThrow(); + } catch(NullPointerException success) { + } + } + + /** + * drainTo(this) throws IAE + */ + public void testDrainToSelf() { + LinkedBlockingQueue q = populatedQueue(SIZE); + try { + q.drainTo(q); + shouldThrow(); + } catch(IllegalArgumentException success) { + } + } + + /** + * drainTo(c) empties queue into another collection c + */ + public void testDrainTo() { + LinkedBlockingQueue q = populatedQueue(SIZE); + ArrayList l = new ArrayList(); + q.drainTo(l); + assertEquals(q.size(), 0); + assertEquals(l.size(), SIZE); + for (int i = 0; i < SIZE; ++i) + assertEquals(l.get(i), new Integer(i)); + } + + /** + * drainTo empties full queue, unblocking a waiting put. + */ + public void testDrainToWithActivePut() { + final LinkedBlockingQueue q = populatedQueue(SIZE); + Thread t = new Thread(new Runnable() { + public void run() { + try { + q.put(new Integer(SIZE+1)); + } catch (InterruptedException ie){ + threadUnexpectedException(); + } + } + }); + try { + t.start(); + ArrayList l = new ArrayList(); + q.drainTo(l); + assertTrue(l.size() >= SIZE); + for (int i = 0; i < SIZE; ++i) + assertEquals(l.get(i), new Integer(i)); + t.join(); + assertTrue(q.size() + l.size() >= SIZE); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * drainTo(null, n) throws NPE + */ + public void testDrainToNullN() { + LinkedBlockingQueue q = populatedQueue(SIZE); + try { + q.drainTo(null, 0); + shouldThrow(); + } catch(NullPointerException success) { + } + } + + /** + * drainTo(this, n) throws IAE + */ + public void testDrainToSelfN() { + LinkedBlockingQueue q = populatedQueue(SIZE); + try { + q.drainTo(q, 0); + shouldThrow(); + } catch(IllegalArgumentException success) { + } + } + + /** + * drainTo(c, n) empties first max {n, size} elements of queue into c + */ + public void testDrainToN() { + for (int i = 0; i < SIZE + 2; ++i) { + LinkedBlockingQueue q = populatedQueue(SIZE); + ArrayList l = new ArrayList(); + q.drainTo(l, i); + int k = (i < SIZE)? i : SIZE; + assertEquals(q.size(), SIZE-k); + assertEquals(l.size(), k); + for (int j = 0; j < k; ++j) + assertEquals(l.get(j), new Integer(j)); + } + } + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/LinkedListTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/LinkedListTest.java new file mode 100755 index 0000000..3a20207 --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/LinkedListTest.java @@ -0,0 +1,453 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.*; +import java.util.concurrent.*; + +public class LinkedListTest extends JSR166TestCase { + public static void main(String[] args) { + junit.textui.TestRunner.run (suite()); + } + + public static Test suite() { + return new TestSuite(LinkedListTest.class); + } + + /** + * Create a queue of given size containing consecutive + * Integers 0 ... n. + */ + private LinkedList populatedQueue(int n) { + LinkedList q = new LinkedList(); + assertTrue(q.isEmpty()); + for(int i = 0; i < n; ++i) + assertTrue(q.offer(new Integer(i))); + assertFalse(q.isEmpty()); + assertEquals(n, q.size()); + return q; + } + + /** + * new queue is empty + */ + public void testConstructor1() { + assertEquals(0, new LinkedList().size()); + } + + /** + * Initializing from null Collection throws NPE + */ + public void testConstructor3() { + try { + LinkedList q = new LinkedList((Collection)null); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * Queue contains all elements of collection used to initialize + + */ + public void testConstructor6() { + try { + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE; ++i) + ints[i] = new Integer(i); + LinkedList q = new LinkedList(Arrays.asList(ints)); + for (int i = 0; i < SIZE; ++i) + assertEquals(ints[i], q.poll()); + } + finally {} + } + + /** + * isEmpty is true before add, false after + */ + public void testEmpty() { + LinkedList q = new LinkedList(); + assertTrue(q.isEmpty()); + q.add(new Integer(1)); + assertFalse(q.isEmpty()); + q.add(new Integer(2)); + q.remove(); + q.remove(); + assertTrue(q.isEmpty()); + } + + /** + * size changes when elements added and removed + */ + public void testSize() { + LinkedList q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(SIZE-i, q.size()); + q.remove(); + } + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.size()); + q.add(new Integer(i)); + } + } + + /** + * offer(null) succeeds + */ + public void testOfferNull() { + try { + LinkedList q = new LinkedList(); + q.offer(null); + } catch (NullPointerException ie) { + unexpectedException(); + } + } + + /** + * Offer succeeds + */ + public void testOffer() { + LinkedList q = new LinkedList(); + assertTrue(q.offer(new Integer(0))); + assertTrue(q.offer(new Integer(1))); + } + + /** + * add succeeds + */ + public void testAdd() { + LinkedList q = new LinkedList(); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.size()); + assertTrue(q.add(new Integer(i))); + } + } + + /** + * addAll(null) throws NPE + */ + public void testAddAll1() { + try { + LinkedList q = new LinkedList(); + q.addAll(null); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * Queue contains all elements, in traversal order, of successful addAll + */ + public void testAddAll5() { + try { + Integer[] empty = new Integer[0]; + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE; ++i) + ints[i] = new Integer(i); + LinkedList q = new LinkedList(); + assertFalse(q.addAll(Arrays.asList(empty))); + assertTrue(q.addAll(Arrays.asList(ints))); + for (int i = 0; i < SIZE; ++i) + assertEquals(ints[i], q.poll()); + } + finally {} + } + + /** + * addAll with too large an index throws IOOBE + */ + public void testAddAll2_IndexOutOfBoundsException() { + try { + LinkedList l = new LinkedList(); + l.add(new Object()); + LinkedList m = new LinkedList(); + m.add(new Object()); + l.addAll(4,m); + shouldThrow(); + } catch(IndexOutOfBoundsException success) {} + } + + /** + * addAll with negative index throws IOOBE + */ + public void testAddAll4_BadIndex() { + try { + LinkedList l = new LinkedList(); + l.add(new Object()); + LinkedList m = new LinkedList(); + m.add(new Object()); + l.addAll(-1,m); + shouldThrow(); + } catch(IndexOutOfBoundsException success){} + } + + /** + * poll succeeds unless empty + */ + public void testPoll() { + LinkedList q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.poll()).intValue()); + } + assertNull(q.poll()); + } + + /** + * peek returns next element, or null if empty + */ + public void testPeek() { + LinkedList q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.peek()).intValue()); + q.poll(); + assertTrue(q.peek() == null || + i != ((Integer)q.peek()).intValue()); + } + assertNull(q.peek()); + } + + /** + * element returns next element, or throws NSEE if empty + */ + public void testElement() { + LinkedList q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.element()).intValue()); + q.poll(); + } + try { + q.element(); + shouldThrow(); + } + catch (NoSuchElementException success) {} + } + + /** + * remove removes next element, or throws NSEE if empty + */ + public void testRemove() { + LinkedList q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.remove()).intValue()); + } + try { + q.remove(); + shouldThrow(); + } catch (NoSuchElementException success){ + } + } + + /** + * remove(x) removes x and returns true if present + */ + public void testRemoveElement() { + LinkedList q = populatedQueue(SIZE); + for (int i = 1; i < SIZE; i+=2) { + assertTrue(q.remove(new Integer(i))); + } + for (int i = 0; i < SIZE; i+=2) { + assertTrue(q.remove(new Integer(i))); + assertFalse(q.remove(new Integer(i+1))); + } + assertTrue(q.isEmpty()); + } + + /** + * contains(x) reports true when elements added but not yet removed + */ + public void testContains() { + LinkedList q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertTrue(q.contains(new Integer(i))); + q.poll(); + assertFalse(q.contains(new Integer(i))); + } + } + + /** + * clear removes all elements + */ + public void testClear() { + LinkedList q = populatedQueue(SIZE); + q.clear(); + assertTrue(q.isEmpty()); + assertEquals(0, q.size()); + q.add(new Integer(1)); + assertFalse(q.isEmpty()); + q.clear(); + assertTrue(q.isEmpty()); + } + + /** + * containsAll(c) is true when c contains a subset of elements + */ + public void testContainsAll() { + LinkedList q = populatedQueue(SIZE); + LinkedList p = new LinkedList(); + for (int i = 0; i < SIZE; ++i) { + assertTrue(q.containsAll(p)); + assertFalse(p.containsAll(q)); + p.add(new Integer(i)); + } + assertTrue(p.containsAll(q)); + } + + /** + * retainAll(c) retains only those elements of c and reports true if changed + */ + public void testRetainAll() { + LinkedList q = populatedQueue(SIZE); + LinkedList p = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + boolean changed = q.retainAll(p); + if (i == 0) + assertFalse(changed); + else + assertTrue(changed); + + assertTrue(q.containsAll(p)); + assertEquals(SIZE-i, q.size()); + p.remove(); + } + } + + /** + * removeAll(c) removes only those elements of c and reports true if changed + */ + public void testRemoveAll() { + for (int i = 1; i < SIZE; ++i) { + LinkedList q = populatedQueue(SIZE); + LinkedList p = populatedQueue(i); + assertTrue(q.removeAll(p)); + assertEquals(SIZE-i, q.size()); + for (int j = 0; j < i; ++j) { + Integer I = (Integer)(p.remove()); + assertFalse(q.contains(I)); + } + } + } + + /** + * toArray contains all elements + */ + public void testToArray() { + LinkedList q = populatedQueue(SIZE); + Object[] o = q.toArray(); + Arrays.sort(o); + for(int i = 0; i < o.length; i++) + assertEquals(o[i], q.poll()); + } + + /** + * toArray(a) contains all elements + */ + public void testToArray2() { + LinkedList q = populatedQueue(SIZE); + Integer[] ints = new Integer[SIZE]; + ints = (Integer[])q.toArray(ints); + Arrays.sort(ints); + for(int i = 0; i < ints.length; i++) + assertEquals(ints[i], q.poll()); + } + + /** + * toArray(null) throws NPE + */ + public void testToArray_BadArg() { + try { + LinkedList l = new LinkedList(); + l.add(new Object()); + Object o[] = l.toArray(null); + shouldThrow(); + } catch(NullPointerException success){} + } + + /** + * toArray with incompatable aray type throws CCE + */ + public void testToArray1_BadArg() { + try { + LinkedList l = new LinkedList(); + l.add(new Integer(5)); + Object o[] = l.toArray(new String[10] ); + shouldThrow(); + } catch(ArrayStoreException success){} + } + + /** + * iterator iterates through all elements + */ + public void testIterator() { + LinkedList q = populatedQueue(SIZE); + int i = 0; + Iterator it = q.iterator(); + while(it.hasNext()) { + assertTrue(q.contains(it.next())); + ++i; + } + assertEquals(i, SIZE); + } + + /** + * iterator ordering is FIFO + */ + public void testIteratorOrdering() { + final LinkedList q = new LinkedList(); + q.add(new Integer(1)); + q.add(new Integer(2)); + q.add(new Integer(3)); + int k = 0; + for (Iterator it = q.iterator(); it.hasNext();) { + int i = ((Integer)(it.next())).intValue(); + assertEquals(++k, i); + } + + assertEquals(3, k); + } + + /** + * iterator.remove removes current element + */ + public void testIteratorRemove () { + final LinkedList q = new LinkedList(); + q.add(new Integer(1)); + q.add(new Integer(2)); + q.add(new Integer(3)); + Iterator it = q.iterator(); + it.next(); + it.remove(); + it = q.iterator(); + assertEquals(it.next(), new Integer(2)); + assertEquals(it.next(), new Integer(3)); + assertFalse(it.hasNext()); + } + + + /** + * toString contains toStrings of elements + */ + public void testToString() { + LinkedList q = populatedQueue(SIZE); + String s = q.toString(); + for (int i = 0; i < SIZE; ++i) { + assertTrue(s.indexOf(String.valueOf(i)) >= 0); + } + } + + /** + * peek returns element inserted with addFirst + */ + public void testAddFirst() { + LinkedList q = populatedQueue(3); + q.addFirst(four); + assertEquals(four,q.peek()); + } + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/LockSupportTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/LockSupportTest.java new file mode 100755 index 0000000..8d74a3a --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/LockSupportTest.java @@ -0,0 +1,169 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.*; +import java.util.concurrent.*; +import java.util.concurrent.locks.*; + +public class LockSupportTest extends JSR166TestCase{ + public static void main(String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(LockSupportTest.class); + } + + /** + * park is released by unpark occurring after park + */ + public void testPark() { + Thread t = new Thread(new Runnable() { + public void run() { + try { + LockSupport.park(); + } catch(Exception e){ + threadUnexpectedException(); + } + } + }); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + LockSupport.unpark(t); + t.join(); + } + catch(Exception e) { + unexpectedException(); + } + } + + /** + * park is released by unpark occurring before park + */ + public void testPark2() { + Thread t = new Thread(new Runnable() { + public void run() { + try { + Thread.sleep(SHORT_DELAY_MS); + LockSupport.park(); + } catch(Exception e){ + threadUnexpectedException(); + } + } + }); + try { + t.start(); + LockSupport.unpark(t); + t.join(); + } + catch(Exception e) { + unexpectedException(); + } + } + + /** + * park is released by interrupt + */ + public void testPark3() { + Thread t = new Thread(new Runnable() { + public void run() { + try { + LockSupport.park(); + threadAssertTrue(Thread.interrupted()); + } catch(Exception e){ + threadUnexpectedException(); + } + } + }); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } + catch(Exception e) { + unexpectedException(); + } + } + + /** + * park returns if interrupted before park + */ + public void testPark4() { + final ReentrantLock lock = new ReentrantLock(); + lock.lock(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + lock.lock(); + LockSupport.park(); + } catch(Exception e){ + threadUnexpectedException(); + } + } + }); + try { + t.start(); + t.interrupt(); + lock.unlock(); + t.join(); + } + catch(Exception e) { + unexpectedException(); + } + } + + /** + * parkNanos times out if not unparked + */ + public void testParkNanos() { + Thread t = new Thread(new Runnable() { + public void run() { + try { + LockSupport.parkNanos(1000); + } catch(Exception e){ + threadUnexpectedException(); + } + } + }); + try { + t.start(); + t.join(); + } + catch(Exception e) { + unexpectedException(); + } + } + + + /** + * parkUntil times out if not unparked + */ + public void testParkUntil() { + Thread t = new Thread(new Runnable() { + public void run() { + try { + long d = new Date().getTime() + 100; + LockSupport.parkUntil(d); + } catch(Exception e){ + threadUnexpectedException(); + } + } + }); + try { + t.start(); + t.join(); + } + catch(Exception e) { + unexpectedException(); + } + } +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/PriorityBlockingQueueTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/PriorityBlockingQueueTest.java new file mode 100755 index 0000000..b258963 --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/PriorityBlockingQueueTest.java @@ -0,0 +1,943 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.*; +import java.util.concurrent.*; +import java.io.*; + +public class PriorityBlockingQueueTest extends JSR166TestCase { + public static void main(String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(PriorityBlockingQueueTest.class); + } + + private static final int NOCAP = Integer.MAX_VALUE; + + /** Sample Comparator */ + static class MyReverseComparator implements Comparator { + public int compare(Object x, Object y) { + int i = ((Integer)x).intValue(); + int j = ((Integer)y).intValue(); + if (i < j) return 1; + if (i > j) return -1; + return 0; + } + } + + /** + * Create a queue of given size containing consecutive + * Integers 0 ... n. + */ + private PriorityBlockingQueue populatedQueue(int n) { + PriorityBlockingQueue q = new PriorityBlockingQueue(n); + assertTrue(q.isEmpty()); + for(int i = n-1; i >= 0; i-=2) + assertTrue(q.offer(new Integer(i))); + for(int i = (n & 1); i < n; i+=2) + assertTrue(q.offer(new Integer(i))); + assertFalse(q.isEmpty()); + assertEquals(NOCAP, q.remainingCapacity()); + assertEquals(n, q.size()); + return q; + } + + /** + * A new queue has unbounded capacity + */ + public void testConstructor1() { + assertEquals(NOCAP, new PriorityBlockingQueue(SIZE).remainingCapacity()); + } + + /** + * Constructor throws IAE if capacity argument nonpositive + */ + public void testConstructor2() { + try { + PriorityBlockingQueue q = new PriorityBlockingQueue(0); + shouldThrow(); + } + catch (IllegalArgumentException success) {} + } + + /** + * Initializing from null Collection throws NPE + */ + public void testConstructor3() { + try { + PriorityBlockingQueue q = new PriorityBlockingQueue(null); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * Initializing from Collection of null elements throws NPE + */ + public void testConstructor4() { + try { + Integer[] ints = new Integer[SIZE]; + PriorityBlockingQueue q = new PriorityBlockingQueue(Arrays.asList(ints)); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * Initializing from Collection with some null elements throws NPE + */ + public void testConstructor5() { + try { + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE-1; ++i) + ints[i] = new Integer(i); + PriorityBlockingQueue q = new PriorityBlockingQueue(Arrays.asList(ints)); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * Queue contains all elements of collection used to initialize + */ + public void testConstructor6() { + try { + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE; ++i) + ints[i] = new Integer(i); + PriorityBlockingQueue q = new PriorityBlockingQueue(Arrays.asList(ints)); + for (int i = 0; i < SIZE; ++i) + assertEquals(ints[i], q.poll()); + } + finally {} + } + + /** + * The comparator used in constructor is used + */ + public void testConstructor7() { + try { + MyReverseComparator cmp = new MyReverseComparator(); + PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE, cmp); + assertEquals(cmp, q.comparator()); + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE; ++i) + ints[i] = new Integer(i); + q.addAll(Arrays.asList(ints)); + for (int i = SIZE-1; i >= 0; --i) + assertEquals(ints[i], q.poll()); + } + finally {} + } + + /** + * isEmpty is true before add, false after + */ + public void testEmpty() { + PriorityBlockingQueue q = new PriorityBlockingQueue(2); + assertTrue(q.isEmpty()); + assertEquals(NOCAP, q.remainingCapacity()); + q.add(one); + assertFalse(q.isEmpty()); + q.add(two); + q.remove(); + q.remove(); + assertTrue(q.isEmpty()); + } + + /** + * remainingCapacity does not change when elements added or removed, + * but size does + */ + public void testRemainingCapacity() { + PriorityBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(NOCAP, q.remainingCapacity()); + assertEquals(SIZE-i, q.size()); + q.remove(); + } + for (int i = 0; i < SIZE; ++i) { + assertEquals(NOCAP, q.remainingCapacity()); + assertEquals(i, q.size()); + q.add(new Integer(i)); + } + } + + /** + * offer(null) throws NPE + */ + public void testOfferNull() { + try { + PriorityBlockingQueue q = new PriorityBlockingQueue(1); + q.offer(null); + shouldThrow(); + } catch (NullPointerException success) { } + } + + /** + * add(null) throws NPE + */ + public void testAddNull() { + try { + PriorityBlockingQueue q = new PriorityBlockingQueue(1); + q.add(null); + shouldThrow(); + } catch (NullPointerException success) { } + } + + /** + * Offer of comparable element succeeds + */ + public void testOffer() { + PriorityBlockingQueue q = new PriorityBlockingQueue(1); + assertTrue(q.offer(zero)); + assertTrue(q.offer(one)); + } + + /** + * Offer of non-Comparable throws CCE + */ + public void testOfferNonComparable() { + try { + PriorityBlockingQueue q = new PriorityBlockingQueue(1); + q.offer(new Object()); + q.offer(new Object()); + q.offer(new Object()); + shouldThrow(); + } + catch(ClassCastException success) {} + } + + /** + * add of comparable succeeds + */ + public void testAdd() { + PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.size()); + assertTrue(q.add(new Integer(i))); + } + } + + /** + * addAll(null) throws NPE + */ + public void testAddAll1() { + try { + PriorityBlockingQueue q = new PriorityBlockingQueue(1); + q.addAll(null); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * addAll(this) throws IAE + */ + public void testAddAllSelf() { + try { + PriorityBlockingQueue q = populatedQueue(SIZE); + q.addAll(q); + shouldThrow(); + } + catch (IllegalArgumentException success) {} + } + + /** + * addAll of a collection with null elements throws NPE + */ + public void testAddAll2() { + try { + PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE); + Integer[] ints = new Integer[SIZE]; + q.addAll(Arrays.asList(ints)); + shouldThrow(); + } + catch (NullPointerException success) {} + } + /** + * addAll of a collection with any null elements throws NPE after + * possibly adding some elements + */ + public void testAddAll3() { + try { + PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE); + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE-1; ++i) + ints[i] = new Integer(i); + q.addAll(Arrays.asList(ints)); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * Queue contains all elements of successful addAll + */ + public void testAddAll5() { + try { + Integer[] empty = new Integer[0]; + Integer[] ints = new Integer[SIZE]; + for (int i = SIZE-1; i >= 0; --i) + ints[i] = new Integer(i); + PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE); + assertFalse(q.addAll(Arrays.asList(empty))); + assertTrue(q.addAll(Arrays.asList(ints))); + for (int i = 0; i < SIZE; ++i) + assertEquals(ints[i], q.poll()); + } + finally {} + } + + /** + * put(null) throws NPE + */ + public void testPutNull() { + try { + PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE); + q.put(null); + shouldThrow(); + } + catch (NullPointerException success){ + } + } + + /** + * all elements successfully put are contained + */ + public void testPut() { + try { + PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + Integer I = new Integer(i); + q.put(I); + assertTrue(q.contains(I)); + } + assertEquals(SIZE, q.size()); + } + finally { + } + } + + /** + * put doesn't block waiting for take + */ + public void testPutWithTake() { + final PriorityBlockingQueue q = new PriorityBlockingQueue(2); + Thread t = new Thread(new Runnable() { + public void run() { + int added = 0; + try { + q.put(new Integer(0)); + ++added; + q.put(new Integer(0)); + ++added; + q.put(new Integer(0)); + ++added; + q.put(new Integer(0)); + ++added; + threadAssertTrue(added == 4); + } finally { + } + } + }); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + q.take(); + t.interrupt(); + t.join(); + } catch (Exception e){ + unexpectedException(); + } + } + + /** + * timed offer does not time out + */ + public void testTimedOffer() { + final PriorityBlockingQueue q = new PriorityBlockingQueue(2); + Thread t = new Thread(new Runnable() { + public void run() { + try { + q.put(new Integer(0)); + q.put(new Integer(0)); + threadAssertTrue(q.offer(new Integer(0), SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + threadAssertTrue(q.offer(new Integer(0), LONG_DELAY_MS, TimeUnit.MILLISECONDS)); + } finally { } + } + }); + + try { + t.start(); + Thread.sleep(SMALL_DELAY_MS); + t.interrupt(); + t.join(); + } catch (Exception e){ + unexpectedException(); + } + } + + /** + * take retrieves elements in priority order + */ + public void testTake() { + try { + PriorityBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.take()).intValue()); + } + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * take blocks interruptibly when empty + */ + public void testTakeFromEmpty() { + final PriorityBlockingQueue q = new PriorityBlockingQueue(2); + Thread t = new Thread(new Runnable() { + public void run() { + try { + q.take(); + threadShouldThrow(); + } catch (InterruptedException success){ } + } + }); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } catch (Exception e){ + unexpectedException(); + } + } + + /** + * Take removes existing elements until empty, then blocks interruptibly + */ + public void testBlockingTake() { + Thread t = new Thread(new Runnable() { + public void run() { + try { + PriorityBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + threadAssertEquals(i, ((Integer)q.take()).intValue()); + } + q.take(); + threadShouldThrow(); + } catch (InterruptedException success){ + } + }}); + t.start(); + try { + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } + catch (InterruptedException ie) { + unexpectedException(); + } + } + + + /** + * poll succeeds unless empty + */ + public void testPoll() { + PriorityBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.poll()).intValue()); + } + assertNull(q.poll()); + } + + /** + * timed pool with zero timeout succeeds when non-empty, else times out + */ + public void testTimedPoll0() { + try { + PriorityBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.poll(0, TimeUnit.MILLISECONDS)).intValue()); + } + assertNull(q.poll(0, TimeUnit.MILLISECONDS)); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * timed pool with nonzero timeout succeeds when non-empty, else times out + */ + public void testTimedPoll() { + try { + PriorityBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)).intValue()); + } + assertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * Interrupted timed poll throws InterruptedException instead of + * returning timeout status + */ + public void testInterruptedTimedPoll() { + Thread t = new Thread(new Runnable() { + public void run() { + try { + PriorityBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + threadAssertEquals(i, ((Integer)q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)).intValue()); + } + threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + } catch (InterruptedException success){ + } + }}); + t.start(); + try { + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } + catch (InterruptedException ie) { + unexpectedException(); + } + } + + /** + * timed poll before a delayed offer fails; after offer succeeds; + * on interruption throws + */ + public void testTimedPollWithOffer() { + final PriorityBlockingQueue q = new PriorityBlockingQueue(2); + Thread t = new Thread(new Runnable() { + public void run() { + try { + threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS); + q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS); + threadShouldThrow(); + } catch (InterruptedException success) { } + } + }); + try { + t.start(); + Thread.sleep(SMALL_DELAY_MS); + assertTrue(q.offer(new Integer(0), SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + t.interrupt(); + t.join(); + } catch (Exception e){ + unexpectedException(); + } + } + + + /** + * peek returns next element, or null if empty + */ + public void testPeek() { + PriorityBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.peek()).intValue()); + q.poll(); + assertTrue(q.peek() == null || + i != ((Integer)q.peek()).intValue()); + } + assertNull(q.peek()); + } + + /** + * element returns next element, or throws NSEE if empty + */ + public void testElement() { + PriorityBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.element()).intValue()); + q.poll(); + } + try { + q.element(); + shouldThrow(); + } + catch (NoSuchElementException success) {} + } + + /** + * remove removes next element, or throws NSEE if empty + */ + public void testRemove() { + PriorityBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.remove()).intValue()); + } + try { + q.remove(); + shouldThrow(); + } catch (NoSuchElementException success){ + } + } + + /** + * remove(x) removes x and returns true if present + */ + public void testRemoveElement() { + PriorityBlockingQueue q = populatedQueue(SIZE); + for (int i = 1; i < SIZE; i+=2) { + assertTrue(q.remove(new Integer(i))); + } + for (int i = 0; i < SIZE; i+=2) { + assertTrue(q.remove(new Integer(i))); + assertFalse(q.remove(new Integer(i+1))); + } + assertTrue(q.isEmpty()); + } + + /** + * contains(x) reports true when elements added but not yet removed + */ + public void testContains() { + PriorityBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertTrue(q.contains(new Integer(i))); + q.poll(); + assertFalse(q.contains(new Integer(i))); + } + } + + /** + * clear removes all elements + */ + public void testClear() { + PriorityBlockingQueue q = populatedQueue(SIZE); + q.clear(); + assertTrue(q.isEmpty()); + assertEquals(0, q.size()); + assertEquals(NOCAP, q.remainingCapacity()); + q.add(new Integer(1)); + assertFalse(q.isEmpty()); + q.clear(); + assertTrue(q.isEmpty()); + } + + /** + * containsAll(c) is true when c contains a subset of elements + */ + public void testContainsAll() { + PriorityBlockingQueue q = populatedQueue(SIZE); + PriorityBlockingQueue p = new PriorityBlockingQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertTrue(q.containsAll(p)); + assertFalse(p.containsAll(q)); + p.add(new Integer(i)); + } + assertTrue(p.containsAll(q)); + } + + /** + * retainAll(c) retains only those elements of c and reports true if changed + */ + public void testRetainAll() { + PriorityBlockingQueue q = populatedQueue(SIZE); + PriorityBlockingQueue p = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + boolean changed = q.retainAll(p); + if (i == 0) + assertFalse(changed); + else + assertTrue(changed); + + assertTrue(q.containsAll(p)); + assertEquals(SIZE-i, q.size()); + p.remove(); + } + } + + /** + * removeAll(c) removes only those elements of c and reports true if changed + */ + public void testRemoveAll() { + for (int i = 1; i < SIZE; ++i) { + PriorityBlockingQueue q = populatedQueue(SIZE); + PriorityBlockingQueue p = populatedQueue(i); + assertTrue(q.removeAll(p)); + assertEquals(SIZE-i, q.size()); + for (int j = 0; j < i; ++j) { + Integer I = (Integer)(p.remove()); + assertFalse(q.contains(I)); + } + } + } + + /** + * toArray contains all elements + */ + public void testToArray() { + PriorityBlockingQueue q = populatedQueue(SIZE); + Object[] o = q.toArray(); + Arrays.sort(o); + try { + for(int i = 0; i < o.length; i++) + assertEquals(o[i], q.take()); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * toArray(a) contains all elements + */ + public void testToArray2() { + PriorityBlockingQueue q = populatedQueue(SIZE); + Integer[] ints = new Integer[SIZE]; + ints = (Integer[])q.toArray(ints); + Arrays.sort(ints); + try { + for(int i = 0; i < ints.length; i++) + assertEquals(ints[i], q.take()); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * toArray(null) throws NPE + */ + public void testToArray_BadArg() { + try { + PriorityBlockingQueue q = populatedQueue(SIZE); + Object o[] = q.toArray(null); + shouldThrow(); + } catch(NullPointerException success){} + } + + /** + * toArray with incompatible array type throws CCE + */ + public void testToArray1_BadArg() { + try { + PriorityBlockingQueue q = populatedQueue(SIZE); + Object o[] = q.toArray(new String[10] ); + shouldThrow(); + } catch(ArrayStoreException success){} + } + + /** + * iterator iterates through all elements + */ + public void testIterator() { + PriorityBlockingQueue q = populatedQueue(SIZE); + int i = 0; + Iterator it = q.iterator(); + while(it.hasNext()) { + assertTrue(q.contains(it.next())); + ++i; + } + assertEquals(i, SIZE); + } + + /** + * iterator.remove removes current element + */ + public void testIteratorRemove () { + final PriorityBlockingQueue q = new PriorityBlockingQueue(3); + q.add(new Integer(2)); + q.add(new Integer(1)); + q.add(new Integer(3)); + + Iterator it = q.iterator(); + it.next(); + it.remove(); + + it = q.iterator(); + assertEquals(it.next(), new Integer(2)); + assertEquals(it.next(), new Integer(3)); + assertFalse(it.hasNext()); + } + + + /** + * toString contains toStrings of elements + */ + public void testToString() { + PriorityBlockingQueue q = populatedQueue(SIZE); + String s = q.toString(); + for (int i = 0; i < SIZE; ++i) { + assertTrue(s.indexOf(String.valueOf(i)) >= 0); + } + } + + /** + * offer transfers elements across Executor tasks + */ + public void testPollInExecutor() { + final PriorityBlockingQueue q = new PriorityBlockingQueue(2); + ExecutorService executor = Executors.newFixedThreadPool(2); + executor.execute(new Runnable() { + public void run() { + threadAssertNull(q.poll()); + try { + threadAssertTrue(null != q.poll(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS)); + threadAssertTrue(q.isEmpty()); + } + catch (InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + executor.execute(new Runnable() { + public void run() { + try { + Thread.sleep(SMALL_DELAY_MS); + q.put(new Integer(1)); + } + catch (InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + joinPool(executor); + } + + /** + * A deserialized serialized queue has same elements + */ + public void testSerialization() { + PriorityBlockingQueue q = populatedQueue(SIZE); + try { + ByteArrayOutputStream bout = new ByteArrayOutputStream(10000); + ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout)); + out.writeObject(q); + out.close(); + + ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); + ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin)); + PriorityBlockingQueue r = (PriorityBlockingQueue)in.readObject(); + assertEquals(q.size(), r.size()); + while (!q.isEmpty()) + assertEquals(q.remove(), r.remove()); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * drainTo(null) throws NPE + */ + public void testDrainToNull() { + PriorityBlockingQueue q = populatedQueue(SIZE); + try { + q.drainTo(null); + shouldThrow(); + } catch(NullPointerException success) { + } + } + + /** + * drainTo(this) throws IAE + */ + public void testDrainToSelf() { + PriorityBlockingQueue q = populatedQueue(SIZE); + try { + q.drainTo(q); + shouldThrow(); + } catch(IllegalArgumentException success) { + } + } + + /** + * drainTo(c) empties queue into another collection c + */ + public void testDrainTo() { + PriorityBlockingQueue q = populatedQueue(SIZE); + ArrayList l = new ArrayList(); + q.drainTo(l); + assertEquals(q.size(), 0); + assertEquals(l.size(), SIZE); + for (int i = 0; i < SIZE; ++i) + assertEquals(l.get(i), new Integer(i)); + } + + /** + * drainTo empties queue + */ + public void testDrainToWithActivePut() { + final PriorityBlockingQueue q = populatedQueue(SIZE); + Thread t = new Thread(new Runnable() { + public void run() { + q.put(new Integer(SIZE+1)); + } + }); + try { + t.start(); + ArrayList l = new ArrayList(); + q.drainTo(l); + assertTrue(l.size() >= SIZE); + for (int i = 0; i < SIZE; ++i) + assertEquals(l.get(i), new Integer(i)); + t.join(); + assertTrue(q.size() + l.size() >= SIZE); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * drainTo(null, n) throws NPE + */ + public void testDrainToNullN() { + PriorityBlockingQueue q = populatedQueue(SIZE); + try { + q.drainTo(null, 0); + shouldThrow(); + } catch(NullPointerException success) { + } + } + + /** + * drainTo(this, n) throws IAE + */ + public void testDrainToSelfN() { + PriorityBlockingQueue q = populatedQueue(SIZE); + try { + q.drainTo(q, 0); + shouldThrow(); + } catch(IllegalArgumentException success) { + } + } + + /** + * drainTo(c, n) empties first max {n, size} elements of queue into c + */ + public void testDrainToN() { + for (int i = 0; i < SIZE + 2; ++i) { + PriorityBlockingQueue q = populatedQueue(SIZE); + ArrayList l = new ArrayList(); + q.drainTo(l, i); + int k = (i < SIZE)? i : SIZE; + assertEquals(q.size(), SIZE-k); + assertEquals(l.size(), k); + for (int j = 0; j < k; ++j) + assertTrue(l.contains(new Integer(j))); + } + } + + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/PriorityQueueTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/PriorityQueueTest.java new file mode 100755 index 0000000..409e1ed --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/PriorityQueueTest.java @@ -0,0 +1,515 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.*; +import java.util.concurrent.*; +import java.io.*; + +public class PriorityQueueTest extends JSR166TestCase { + public static void main(String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(PriorityQueueTest.class); + } + + static class MyReverseComparator implements Comparator { + public int compare(Object x, Object y) { + int i = ((Integer)x).intValue(); + int j = ((Integer)y).intValue(); + if (i < j) return 1; + if (i > j) return -1; + return 0; + } + } + + /** + * Create a queue of given size containing consecutive + * Integers 0 ... n. + */ + private PriorityQueue populatedQueue(int n) { + PriorityQueue q = new PriorityQueue(n); + assertTrue(q.isEmpty()); + for(int i = n-1; i >= 0; i-=2) + assertTrue(q.offer(new Integer(i))); + for(int i = (n & 1); i < n; i+=2) + assertTrue(q.offer(new Integer(i))); + assertFalse(q.isEmpty()); + assertEquals(n, q.size()); + return q; + } + + /** + * A new queue has unbounded capacity + */ + public void testConstructor1() { + assertEquals(0, new PriorityQueue(SIZE).size()); + } + + /** + * Constructor throws IAE if capacity argument nonpositive + */ + public void testConstructor2() { + try { + PriorityQueue q = new PriorityQueue(0); + shouldThrow(); + } + catch (IllegalArgumentException success) {} + } + + /** + * Initializing from null Collection throws NPE + */ + public void testConstructor3() { + try { + PriorityQueue q = new PriorityQueue((Collection)null); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * Initializing from Collection of null elements throws NPE + */ + public void testConstructor4() { + try { + Integer[] ints = new Integer[SIZE]; + PriorityQueue q = new PriorityQueue(Arrays.asList(ints)); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * Initializing from Collection with some null elements throws NPE + */ + public void testConstructor5() { + try { + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE-1; ++i) + ints[i] = new Integer(i); + PriorityQueue q = new PriorityQueue(Arrays.asList(ints)); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * Queue contains all elements of collection used to initialize + */ + public void testConstructor6() { + try { + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE; ++i) + ints[i] = new Integer(i); + PriorityQueue q = new PriorityQueue(Arrays.asList(ints)); + for (int i = 0; i < SIZE; ++i) + assertEquals(ints[i], q.poll()); + } + finally {} + } + + /** + * The comparator used in constructor is used + */ + public void testConstructor7() { + try { + MyReverseComparator cmp = new MyReverseComparator(); + PriorityQueue q = new PriorityQueue(SIZE, cmp); + assertEquals(cmp, q.comparator()); + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE; ++i) + ints[i] = new Integer(i); + q.addAll(Arrays.asList(ints)); + for (int i = SIZE-1; i >= 0; --i) + assertEquals(ints[i], q.poll()); + } + finally {} + } + + /** + * isEmpty is true before add, false after + */ + public void testEmpty() { + PriorityQueue q = new PriorityQueue(2); + assertTrue(q.isEmpty()); + q.add(new Integer(1)); + assertFalse(q.isEmpty()); + q.add(new Integer(2)); + q.remove(); + q.remove(); + assertTrue(q.isEmpty()); + } + + /** + * size changes when elements added and removed + */ + public void testSize() { + PriorityQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(SIZE-i, q.size()); + q.remove(); + } + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.size()); + q.add(new Integer(i)); + } + } + + /** + * offer(null) throws NPE + */ + public void testOfferNull() { + try { + PriorityQueue q = new PriorityQueue(1); + q.offer(null); + shouldThrow(); + } catch (NullPointerException success) { } + } + + /** + * add(null) throws NPE + */ + public void testAddNull() { + try { + PriorityQueue q = new PriorityQueue(1); + q.add(null); + shouldThrow(); + } catch (NullPointerException success) { } + } + + /** + * Offer of comparable element succeeds + */ + public void testOffer() { + PriorityQueue q = new PriorityQueue(1); + assertTrue(q.offer(zero)); + assertTrue(q.offer(one)); + } + + /** + * Offer of non-Comparable throws CCE + */ + public void testOfferNonComparable() { + try { + PriorityQueue q = new PriorityQueue(1); + q.offer(new Object()); + q.offer(new Object()); + q.offer(new Object()); + shouldThrow(); + } + catch(ClassCastException success) {} + } + + /** + * add of comparable succeeds + */ + public void testAdd() { + PriorityQueue q = new PriorityQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.size()); + assertTrue(q.add(new Integer(i))); + } + } + + /** + * addAll(null) throws NPE + */ + public void testAddAll1() { + try { + PriorityQueue q = new PriorityQueue(1); + q.addAll(null); + shouldThrow(); + } + catch (NullPointerException success) {} + } + /** + * addAll of a collection with null elements throws NPE + */ + public void testAddAll2() { + try { + PriorityQueue q = new PriorityQueue(SIZE); + Integer[] ints = new Integer[SIZE]; + q.addAll(Arrays.asList(ints)); + shouldThrow(); + } + catch (NullPointerException success) {} + } + /** + * addAll of a collection with any null elements throws NPE after + * possibly adding some elements + */ + public void testAddAll3() { + try { + PriorityQueue q = new PriorityQueue(SIZE); + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE-1; ++i) + ints[i] = new Integer(i); + q.addAll(Arrays.asList(ints)); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * Queue contains all elements of successful addAll + */ + public void testAddAll5() { + try { + Integer[] empty = new Integer[0]; + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE; ++i) + ints[i] = new Integer(SIZE-1-i); + PriorityQueue q = new PriorityQueue(SIZE); + assertFalse(q.addAll(Arrays.asList(empty))); + assertTrue(q.addAll(Arrays.asList(ints))); + for (int i = 0; i < SIZE; ++i) + assertEquals(new Integer(i), q.poll()); + } + finally {} + } + + /** + * poll succeeds unless empty + */ + public void testPoll() { + PriorityQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.poll()).intValue()); + } + assertNull(q.poll()); + } + + /** + * peek returns next element, or null if empty + */ + public void testPeek() { + PriorityQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.peek()).intValue()); + q.poll(); + assertTrue(q.peek() == null || + i != ((Integer)q.peek()).intValue()); + } + assertNull(q.peek()); + } + + /** + * element returns next element, or throws NSEE if empty + */ + public void testElement() { + PriorityQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.element()).intValue()); + q.poll(); + } + try { + q.element(); + shouldThrow(); + } + catch (NoSuchElementException success) {} + } + + /** + * remove removes next element, or throws NSEE if empty + */ + public void testRemove() { + PriorityQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, ((Integer)q.remove()).intValue()); + } + try { + q.remove(); + shouldThrow(); + } catch (NoSuchElementException success){ + } + } + + /** + * remove(x) removes x and returns true if present + */ + public void testRemoveElement() { + PriorityQueue q = populatedQueue(SIZE); + for (int i = 1; i < SIZE; i+=2) { + assertTrue(q.remove(new Integer(i))); + } + for (int i = 0; i < SIZE; i+=2) { + assertTrue(q.remove(new Integer(i))); + assertFalse(q.remove(new Integer(i+1))); + } + assertTrue(q.isEmpty()); + } + + /** + * contains(x) reports true when elements added but not yet removed + */ + public void testContains() { + PriorityQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertTrue(q.contains(new Integer(i))); + q.poll(); + assertFalse(q.contains(new Integer(i))); + } + } + + /** + * clear removes all elements + */ + public void testClear() { + PriorityQueue q = populatedQueue(SIZE); + q.clear(); + assertTrue(q.isEmpty()); + assertEquals(0, q.size()); + q.add(new Integer(1)); + assertFalse(q.isEmpty()); + q.clear(); + assertTrue(q.isEmpty()); + } + + /** + * containsAll(c) is true when c contains a subset of elements + */ + public void testContainsAll() { + PriorityQueue q = populatedQueue(SIZE); + PriorityQueue p = new PriorityQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertTrue(q.containsAll(p)); + assertFalse(p.containsAll(q)); + p.add(new Integer(i)); + } + assertTrue(p.containsAll(q)); + } + + /** + * retainAll(c) retains only those elements of c and reports true if changed + */ + public void testRetainAll() { + PriorityQueue q = populatedQueue(SIZE); + PriorityQueue p = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + boolean changed = q.retainAll(p); + if (i == 0) + assertFalse(changed); + else + assertTrue(changed); + + assertTrue(q.containsAll(p)); + assertEquals(SIZE-i, q.size()); + p.remove(); + } + } + + /** + * removeAll(c) removes only those elements of c and reports true if changed + */ + public void testRemoveAll() { + for (int i = 1; i < SIZE; ++i) { + PriorityQueue q = populatedQueue(SIZE); + PriorityQueue p = populatedQueue(i); + assertTrue(q.removeAll(p)); + assertEquals(SIZE-i, q.size()); + for (int j = 0; j < i; ++j) { + Integer I = (Integer)(p.remove()); + assertFalse(q.contains(I)); + } + } + } + + /** + * toArray contains all elements + */ + public void testToArray() { + PriorityQueue q = populatedQueue(SIZE); + Object[] o = q.toArray(); + Arrays.sort(o); + for(int i = 0; i < o.length; i++) + assertEquals(o[i], q.poll()); + } + + /** + * toArray(a) contains all elements + */ + public void testToArray2() { + PriorityQueue q = populatedQueue(SIZE); + Integer[] ints = new Integer[SIZE]; + ints = (Integer[])q.toArray(ints); + Arrays.sort(ints); + for(int i = 0; i < ints.length; i++) + assertEquals(ints[i], q.poll()); + } + + /** + * iterator iterates through all elements + */ + public void testIterator() { + PriorityQueue q = populatedQueue(SIZE); + int i = 0; + Iterator it = q.iterator(); + while(it.hasNext()) { + assertTrue(q.contains(it.next())); + ++i; + } + assertEquals(i, SIZE); + } + + /** + * iterator.remove removes current element + */ + public void testIteratorRemove () { + final PriorityQueue q = new PriorityQueue(3); + q.add(new Integer(2)); + q.add(new Integer(1)); + q.add(new Integer(3)); + + Iterator it = q.iterator(); + it.next(); + it.remove(); + + it = q.iterator(); + assertEquals(it.next(), new Integer(2)); + assertEquals(it.next(), new Integer(3)); + assertFalse(it.hasNext()); + } + + + /** + * toString contains toStrings of elements + */ + public void testToString() { + PriorityQueue q = populatedQueue(SIZE); + String s = q.toString(); + for (int i = 0; i < SIZE; ++i) { + assertTrue(s.indexOf(String.valueOf(i)) >= 0); + } + } + + /** + * A deserialized serialized queue has same elements + */ + public void testSerialization() { + PriorityQueue q = populatedQueue(SIZE); + try { + ByteArrayOutputStream bout = new ByteArrayOutputStream(10000); + ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout)); + out.writeObject(q); + out.close(); + + ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); + ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin)); + PriorityQueue r = (PriorityQueue)in.readObject(); + assertEquals(q.size(), r.size()); + while (!q.isEmpty()) + assertEquals(q.remove(), r.remove()); + } catch(Exception e){ + unexpectedException(); + } + } +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ReentrantLockTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ReentrantLockTest.java new file mode 100755 index 0000000..fdc9f31 --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ReentrantLockTest.java @@ -0,0 +1,1080 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.concurrent.locks.*; +import java.util.concurrent.*; +import java.util.*; +import java.io.*; + +public class ReentrantLockTest extends JSR166TestCase { + public static void main(String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(ReentrantLockTest.class); + } + + /** + * A runnable calling lockInterruptibly + */ + class InterruptibleLockRunnable implements Runnable { + final ReentrantLock lock; + InterruptibleLockRunnable(ReentrantLock l) { lock = l; } + public void run() { + try { + lock.lockInterruptibly(); + } catch(InterruptedException success){} + } + } + + + /** + * A runnable calling lockInterruptibly that expects to be + * interrupted + */ + class InterruptedLockRunnable implements Runnable { + final ReentrantLock lock; + InterruptedLockRunnable(ReentrantLock l) { lock = l; } + public void run() { + try { + lock.lockInterruptibly(); + threadShouldThrow(); + } catch(InterruptedException success){} + } + } + + /** + * Subclass to expose protected methods + */ + static class PublicReentrantLock extends ReentrantLock { + PublicReentrantLock() { super(); } + public Collection<Thread> getQueuedThreads() { + return super.getQueuedThreads(); + } + public Collection<Thread> getWaitingThreads(Condition c) { + return super.getWaitingThreads(c); + } + + + } + + /** + * Constructor sets given fairness + */ + public void testConstructor() { + ReentrantLock rl = new ReentrantLock(); + assertFalse(rl.isFair()); + ReentrantLock r2 = new ReentrantLock(true); + assertTrue(r2.isFair()); + } + + /** + * locking an unlocked lock succeeds + */ + public void testLock() { + ReentrantLock rl = new ReentrantLock(); + rl.lock(); + assertTrue(rl.isLocked()); + rl.unlock(); + } + + /** + * locking an unlocked fair lock succeeds + */ + public void testFairLock() { + ReentrantLock rl = new ReentrantLock(true); + rl.lock(); + assertTrue(rl.isLocked()); + rl.unlock(); + } + + /** + * Unlocking an unlocked lock throws IllegalMonitorStateException + */ + public void testUnlock_IllegalMonitorStateException() { + ReentrantLock rl = new ReentrantLock(); + try { + rl.unlock(); + shouldThrow(); + + } catch(IllegalMonitorStateException success){} + } + + /** + * tryLock on an unlocked lock succeeds + */ + public void testTryLock() { + ReentrantLock rl = new ReentrantLock(); + assertTrue(rl.tryLock()); + assertTrue(rl.isLocked()); + rl.unlock(); + } + + + /** + * hasQueuedThreads reports whether there are waiting threads + */ + public void testhasQueuedThreads() { + final ReentrantLock lock = new ReentrantLock(); + Thread t1 = new Thread(new InterruptedLockRunnable(lock)); + Thread t2 = new Thread(new InterruptibleLockRunnable(lock)); + try { + assertFalse(lock.hasQueuedThreads()); + lock.lock(); + t1.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(lock.hasQueuedThreads()); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(lock.hasQueuedThreads()); + t1.interrupt(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(lock.hasQueuedThreads()); + lock.unlock(); + Thread.sleep(SHORT_DELAY_MS); + assertFalse(lock.hasQueuedThreads()); + t1.join(); + t2.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * getQueueLength reports number of waiting threads + */ + public void testGetQueueLength() { + final ReentrantLock lock = new ReentrantLock(); + Thread t1 = new Thread(new InterruptedLockRunnable(lock)); + Thread t2 = new Thread(new InterruptibleLockRunnable(lock)); + try { + assertEquals(0, lock.getQueueLength()); + lock.lock(); + t1.start(); + Thread.sleep(SHORT_DELAY_MS); + assertEquals(1, lock.getQueueLength()); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + assertEquals(2, lock.getQueueLength()); + t1.interrupt(); + Thread.sleep(SHORT_DELAY_MS); + assertEquals(1, lock.getQueueLength()); + lock.unlock(); + Thread.sleep(SHORT_DELAY_MS); + assertEquals(0, lock.getQueueLength()); + t1.join(); + t2.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * getQueueLength reports number of waiting threads + */ + public void testGetQueueLength_fair() { + final ReentrantLock lock = new ReentrantLock(true); + Thread t1 = new Thread(new InterruptedLockRunnable(lock)); + Thread t2 = new Thread(new InterruptibleLockRunnable(lock)); + try { + assertEquals(0, lock.getQueueLength()); + lock.lock(); + t1.start(); + Thread.sleep(SHORT_DELAY_MS); + assertEquals(1, lock.getQueueLength()); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + assertEquals(2, lock.getQueueLength()); + t1.interrupt(); + Thread.sleep(SHORT_DELAY_MS); + assertEquals(1, lock.getQueueLength()); + lock.unlock(); + Thread.sleep(SHORT_DELAY_MS); + assertEquals(0, lock.getQueueLength()); + t1.join(); + t2.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * hasQueuedThread(null) throws NPE + */ + public void testHasQueuedThreadNPE() { + final ReentrantLock sync = new ReentrantLock(); + try { + sync.hasQueuedThread(null); + shouldThrow(); + } catch (NullPointerException success) { + } + } + + /** + * hasQueuedThread reports whether a thread is queued. + */ + public void testHasQueuedThread() { + final ReentrantLock sync = new ReentrantLock(); + Thread t1 = new Thread(new InterruptedLockRunnable(sync)); + Thread t2 = new Thread(new InterruptibleLockRunnable(sync)); + try { + assertFalse(sync.hasQueuedThread(t1)); + assertFalse(sync.hasQueuedThread(t2)); + sync.lock(); + t1.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(sync.hasQueuedThread(t1)); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(sync.hasQueuedThread(t1)); + assertTrue(sync.hasQueuedThread(t2)); + t1.interrupt(); + Thread.sleep(SHORT_DELAY_MS); + assertFalse(sync.hasQueuedThread(t1)); + assertTrue(sync.hasQueuedThread(t2)); + sync.unlock(); + Thread.sleep(SHORT_DELAY_MS); + assertFalse(sync.hasQueuedThread(t1)); + Thread.sleep(SHORT_DELAY_MS); + assertFalse(sync.hasQueuedThread(t2)); + t1.join(); + t2.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + + /** + * getQueuedThreads includes waiting threads + */ + public void testGetQueuedThreads() { + final PublicReentrantLock lock = new PublicReentrantLock(); + Thread t1 = new Thread(new InterruptedLockRunnable(lock)); + Thread t2 = new Thread(new InterruptibleLockRunnable(lock)); + try { + assertTrue(lock.getQueuedThreads().isEmpty()); + lock.lock(); + assertTrue(lock.getQueuedThreads().isEmpty()); + t1.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(lock.getQueuedThreads().contains(t1)); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(lock.getQueuedThreads().contains(t1)); + assertTrue(lock.getQueuedThreads().contains(t2)); + t1.interrupt(); + Thread.sleep(SHORT_DELAY_MS); + assertFalse(lock.getQueuedThreads().contains(t1)); + assertTrue(lock.getQueuedThreads().contains(t2)); + lock.unlock(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(lock.getQueuedThreads().isEmpty()); + t1.join(); + t2.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + + /** + * timed tryLock is interruptible. + */ + public void testInterruptedException2() { + final ReentrantLock lock = new ReentrantLock(); + lock.lock(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + lock.tryLock(MEDIUM_DELAY_MS,TimeUnit.MILLISECONDS); + threadShouldThrow(); + } catch(InterruptedException success){} + } + }); + try { + t.start(); + t.interrupt(); + } catch(Exception e){ + unexpectedException(); + } + } + + + /** + * TryLock on a locked lock fails + */ + public void testTryLockWhenLocked() { + final ReentrantLock lock = new ReentrantLock(); + lock.lock(); + Thread t = new Thread(new Runnable() { + public void run() { + threadAssertFalse(lock.tryLock()); + } + }); + try { + t.start(); + t.join(); + lock.unlock(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * Timed tryLock on a locked lock times out + */ + public void testTryLock_Timeout() { + final ReentrantLock lock = new ReentrantLock(); + lock.lock(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + threadAssertFalse(lock.tryLock(1, TimeUnit.MILLISECONDS)); + } catch (Exception ex) { + threadUnexpectedException(); + } + } + }); + try { + t.start(); + t.join(); + lock.unlock(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * getHoldCount returns number of recursive holds + */ + public void testGetHoldCount() { + ReentrantLock lock = new ReentrantLock(); + for(int i = 1; i <= SIZE; i++) { + lock.lock(); + assertEquals(i,lock.getHoldCount()); + } + for(int i = SIZE; i > 0; i--) { + lock.unlock(); + assertEquals(i-1,lock.getHoldCount()); + } + } + + + /** + * isLocked is true when locked and false when not + */ + public void testIsLocked() { + final ReentrantLock lock = new ReentrantLock(); + lock.lock(); + assertTrue(lock.isLocked()); + lock.unlock(); + assertFalse(lock.isLocked()); + Thread t = new Thread(new Runnable() { + public void run() { + lock.lock(); + try { + Thread.sleep(SMALL_DELAY_MS); + } + catch(Exception e) { + threadUnexpectedException(); + } + lock.unlock(); + } + }); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(lock.isLocked()); + t.join(); + assertFalse(lock.isLocked()); + } catch(Exception e){ + unexpectedException(); + } + } + + + /** + * lockInterruptibly is interruptible. + */ + public void testLockInterruptibly1() { + final ReentrantLock lock = new ReentrantLock(); + lock.lock(); + Thread t = new Thread(new InterruptedLockRunnable(lock)); + try { + t.start(); + t.interrupt(); + lock.unlock(); + t.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * lockInterruptibly succeeds when unlocked, else is interruptible + */ + public void testLockInterruptibly2() { + final ReentrantLock lock = new ReentrantLock(); + try { + lock.lockInterruptibly(); + } catch(Exception e) { + unexpectedException(); + } + Thread t = new Thread(new InterruptedLockRunnable(lock)); + try { + t.start(); + t.interrupt(); + assertTrue(lock.isLocked()); + assertTrue(lock.isHeldByCurrentThread()); + t.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * Calling await without holding lock throws IllegalMonitorStateException + */ + public void testAwait_IllegalMonitor() { + final ReentrantLock lock = new ReentrantLock(); + final Condition c = lock.newCondition(); + try { + c.await(); + shouldThrow(); + } + catch (IllegalMonitorStateException success) { + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * Calling signal without holding lock throws IllegalMonitorStateException + */ + public void testSignal_IllegalMonitor() { + final ReentrantLock lock = new ReentrantLock(); + final Condition c = lock.newCondition(); + try { + c.signal(); + shouldThrow(); + } + catch (IllegalMonitorStateException success) { + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * awaitNanos without a signal times out + */ + public void testAwaitNanos_Timeout() { + final ReentrantLock lock = new ReentrantLock(); + final Condition c = lock.newCondition(); + try { + lock.lock(); + long t = c.awaitNanos(100); + assertTrue(t <= 0); + lock.unlock(); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * timed await without a signal times out + */ + public void testAwait_Timeout() { + final ReentrantLock lock = new ReentrantLock(); + final Condition c = lock.newCondition(); + try { + lock.lock(); + assertFalse(c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + lock.unlock(); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * awaitUntil without a signal times out + */ + public void testAwaitUntil_Timeout() { + final ReentrantLock lock = new ReentrantLock(); + final Condition c = lock.newCondition(); + try { + lock.lock(); + java.util.Date d = new java.util.Date(); + assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10))); + lock.unlock(); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * await returns when signalled + */ + public void testAwait() { + final ReentrantLock lock = new ReentrantLock(); + final Condition c = lock.newCondition(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + lock.lock(); + c.await(); + lock.unlock(); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + lock.lock(); + c.signal(); + lock.unlock(); + t.join(SHORT_DELAY_MS); + assertFalse(t.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * hasWaiters throws NPE if null + */ + public void testHasWaitersNPE() { + final ReentrantLock lock = new ReentrantLock(); + try { + lock.hasWaiters(null); + shouldThrow(); + } catch (NullPointerException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + /** + * getWaitQueueLength throws NPE if null + */ + public void testGetWaitQueueLengthNPE() { + final ReentrantLock lock = new ReentrantLock(); + try { + lock.getWaitQueueLength(null); + shouldThrow(); + } catch (NullPointerException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + + /** + * getWaitingThreads throws NPE if null + */ + public void testGetWaitingThreadsNPE() { + final PublicReentrantLock lock = new PublicReentrantLock(); + try { + lock.getWaitingThreads(null); + shouldThrow(); + } catch (NullPointerException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + + /** + * hasWaiters throws IAE if not owned + */ + public void testHasWaitersIAE() { + final ReentrantLock lock = new ReentrantLock(); + final Condition c = (lock.newCondition()); + final ReentrantLock lock2 = new ReentrantLock(); + try { + lock2.hasWaiters(c); + shouldThrow(); + } catch (IllegalArgumentException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + /** + * hasWaiters throws IMSE if not locked + */ + public void testHasWaitersIMSE() { + final ReentrantLock lock = new ReentrantLock(); + final Condition c = (lock.newCondition()); + try { + lock.hasWaiters(c); + shouldThrow(); + } catch (IllegalMonitorStateException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + + /** + * getWaitQueueLength throws IAE if not owned + */ + public void testGetWaitQueueLengthIAE() { + final ReentrantLock lock = new ReentrantLock(); + final Condition c = (lock.newCondition()); + final ReentrantLock lock2 = new ReentrantLock(); + try { + lock2.getWaitQueueLength(c); + shouldThrow(); + } catch (IllegalArgumentException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + /** + * getWaitQueueLength throws IMSE if not locked + */ + public void testGetWaitQueueLengthIMSE() { + final ReentrantLock lock = new ReentrantLock(); + final Condition c = (lock.newCondition()); + try { + lock.getWaitQueueLength(c); + shouldThrow(); + } catch (IllegalMonitorStateException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + + /** + * getWaitingThreads throws IAE if not owned + */ + public void testGetWaitingThreadsIAE() { + final PublicReentrantLock lock = new PublicReentrantLock(); + final Condition c = (lock.newCondition()); + final PublicReentrantLock lock2 = new PublicReentrantLock(); + try { + lock2.getWaitingThreads(c); + shouldThrow(); + } catch (IllegalArgumentException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + /** + * getWaitingThreads throws IMSE if not locked + */ + public void testGetWaitingThreadsIMSE() { + final PublicReentrantLock lock = new PublicReentrantLock(); + final Condition c = (lock.newCondition()); + try { + lock.getWaitingThreads(c); + shouldThrow(); + } catch (IllegalMonitorStateException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + + + /** + * hasWaiters returns true when a thread is waiting, else false + */ + public void testHasWaiters() { + final ReentrantLock lock = new ReentrantLock(); + final Condition c = lock.newCondition(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + lock.lock(); + threadAssertFalse(lock.hasWaiters(c)); + threadAssertEquals(0, lock.getWaitQueueLength(c)); + c.await(); + lock.unlock(); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + lock.lock(); + assertTrue(lock.hasWaiters(c)); + assertEquals(1, lock.getWaitQueueLength(c)); + c.signal(); + lock.unlock(); + Thread.sleep(SHORT_DELAY_MS); + lock.lock(); + assertFalse(lock.hasWaiters(c)); + assertEquals(0, lock.getWaitQueueLength(c)); + lock.unlock(); + t.join(SHORT_DELAY_MS); + assertFalse(t.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * getWaitQueueLength returns number of waiting threads + */ + public void testGetWaitQueueLength() { + final ReentrantLock lock = new ReentrantLock(); + final Condition c = lock.newCondition(); + Thread t1 = new Thread(new Runnable() { + public void run() { + try { + lock.lock(); + threadAssertFalse(lock.hasWaiters(c)); + threadAssertEquals(0, lock.getWaitQueueLength(c)); + c.await(); + lock.unlock(); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + Thread t2 = new Thread(new Runnable() { + public void run() { + try { + lock.lock(); + threadAssertTrue(lock.hasWaiters(c)); + threadAssertEquals(1, lock.getWaitQueueLength(c)); + c.await(); + lock.unlock(); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + try { + t1.start(); + Thread.sleep(SHORT_DELAY_MS); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + lock.lock(); + assertTrue(lock.hasWaiters(c)); + assertEquals(2, lock.getWaitQueueLength(c)); + c.signalAll(); + lock.unlock(); + Thread.sleep(SHORT_DELAY_MS); + lock.lock(); + assertFalse(lock.hasWaiters(c)); + assertEquals(0, lock.getWaitQueueLength(c)); + lock.unlock(); + t1.join(SHORT_DELAY_MS); + t2.join(SHORT_DELAY_MS); + assertFalse(t1.isAlive()); + assertFalse(t2.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * getWaitingThreads returns only and all waiting threads + */ + public void testGetWaitingThreads() { + final PublicReentrantLock lock = new PublicReentrantLock(); + final Condition c = lock.newCondition(); + Thread t1 = new Thread(new Runnable() { + public void run() { + try { + lock.lock(); + threadAssertTrue(lock.getWaitingThreads(c).isEmpty()); + c.await(); + lock.unlock(); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + Thread t2 = new Thread(new Runnable() { + public void run() { + try { + lock.lock(); + threadAssertFalse(lock.getWaitingThreads(c).isEmpty()); + c.await(); + lock.unlock(); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + try { + lock.lock(); + assertTrue(lock.getWaitingThreads(c).isEmpty()); + lock.unlock(); + t1.start(); + Thread.sleep(SHORT_DELAY_MS); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + lock.lock(); + assertTrue(lock.hasWaiters(c)); + assertTrue(lock.getWaitingThreads(c).contains(t1)); + assertTrue(lock.getWaitingThreads(c).contains(t2)); + c.signalAll(); + lock.unlock(); + Thread.sleep(SHORT_DELAY_MS); + lock.lock(); + assertFalse(lock.hasWaiters(c)); + assertTrue(lock.getWaitingThreads(c).isEmpty()); + lock.unlock(); + t1.join(SHORT_DELAY_MS); + t2.join(SHORT_DELAY_MS); + assertFalse(t1.isAlive()); + assertFalse(t2.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + + + /** + * awaitUninterruptibly doesn't abort on interrupt + */ + public void testAwaitUninterruptibly() { + final ReentrantLock lock = new ReentrantLock(); + final Condition c = lock.newCondition(); + Thread t = new Thread(new Runnable() { + public void run() { + lock.lock(); + c.awaitUninterruptibly(); + lock.unlock(); + } + }); + + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + lock.lock(); + c.signal(); + lock.unlock(); + assert(t.isInterrupted()); + t.join(SHORT_DELAY_MS); + assertFalse(t.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * await is interruptible + */ + public void testAwait_Interrupt() { + final ReentrantLock lock = new ReentrantLock(); + final Condition c = lock.newCondition(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + lock.lock(); + c.await(); + lock.unlock(); + threadShouldThrow(); + } + catch(InterruptedException success) { + } + } + }); + + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(SHORT_DELAY_MS); + assertFalse(t.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * awaitNanos is interruptible + */ + public void testAwaitNanos_Interrupt() { + final ReentrantLock lock = new ReentrantLock(); + final Condition c = lock.newCondition(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + lock.lock(); + c.awaitNanos(1000 * 1000 * 1000); // 1 sec + lock.unlock(); + threadShouldThrow(); + } + catch(InterruptedException success) { + } + } + }); + + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(SHORT_DELAY_MS); + assertFalse(t.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * awaitUntil is interruptible + */ + public void testAwaitUntil_Interrupt() { + final ReentrantLock lock = new ReentrantLock(); + final Condition c = lock.newCondition(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + lock.lock(); + java.util.Date d = new java.util.Date(); + c.awaitUntil(new java.util.Date(d.getTime() + 10000)); + lock.unlock(); + threadShouldThrow(); + } + catch(InterruptedException success) { + } + } + }); + + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(SHORT_DELAY_MS); + assertFalse(t.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * signalAll wakes up all threads + */ + public void testSignalAll() { + final ReentrantLock lock = new ReentrantLock(); + final Condition c = lock.newCondition(); + Thread t1 = new Thread(new Runnable() { + public void run() { + try { + lock.lock(); + c.await(); + lock.unlock(); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + Thread t2 = new Thread(new Runnable() { + public void run() { + try { + lock.lock(); + c.await(); + lock.unlock(); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + try { + t1.start(); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + lock.lock(); + c.signalAll(); + lock.unlock(); + t1.join(SHORT_DELAY_MS); + t2.join(SHORT_DELAY_MS); + assertFalse(t1.isAlive()); + assertFalse(t2.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * A serialized lock deserializes as unlocked + */ + public void testSerialization() { + ReentrantLock l = new ReentrantLock(); + l.lock(); + l.unlock(); + + try { + ByteArrayOutputStream bout = new ByteArrayOutputStream(10000); + ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout)); + out.writeObject(l); + out.close(); + + ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); + ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin)); + ReentrantLock r = (ReentrantLock) in.readObject(); + r.lock(); + r.unlock(); + } catch(Exception e){ + e.printStackTrace(); + unexpectedException(); + } + } + + /** + * toString indicates current lock state + */ + public void testToString() { + ReentrantLock lock = new ReentrantLock(); + String us = lock.toString(); + assertTrue(us.indexOf("Unlocked") >= 0); + lock.lock(); + String ls = lock.toString(); + assertTrue(ls.indexOf("Locked") >= 0); + } + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ReentrantReadWriteLockTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ReentrantReadWriteLockTest.java new file mode 100644 index 0000000..8925b42 --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ReentrantReadWriteLockTest.java @@ -0,0 +1,1321 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.concurrent.locks.*; +import java.util.concurrent.*; +import java.io.*; +import java.util.*; + +public class ReentrantReadWriteLockTest extends JSR166TestCase { + public static void main(String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(ReentrantReadWriteLockTest.class); + } + + /** + * A runnable calling lockInterruptibly + */ + class InterruptibleLockRunnable implements Runnable { + final ReentrantReadWriteLock lock; + InterruptibleLockRunnable(ReentrantReadWriteLock l) { lock = l; } + public void run() { + try { + lock.writeLock().lockInterruptibly(); + } catch(InterruptedException success){} + } + } + + + /** + * A runnable calling lockInterruptibly that expects to be + * interrupted + */ + class InterruptedLockRunnable implements Runnable { + final ReentrantReadWriteLock lock; + InterruptedLockRunnable(ReentrantReadWriteLock l) { lock = l; } + public void run() { + try { + lock.writeLock().lockInterruptibly(); + threadShouldThrow(); + } catch(InterruptedException success){} + } + } + + /** + * Subclass to expose protected methods + */ + static class PublicReentrantReadWriteLock extends ReentrantReadWriteLock { + PublicReentrantReadWriteLock() { super(); } + public Collection<Thread> getQueuedThreads() { + return super.getQueuedThreads(); + } + public Collection<Thread> getWaitingThreads(Condition c) { + return super.getWaitingThreads(c); + } + } + + /** + * Constructor sets given fairness, and is in unlocked state + */ + public void testConstructor() { + ReentrantReadWriteLock rl = new ReentrantReadWriteLock(); + assertFalse(rl.isFair()); + assertFalse(rl.isWriteLocked()); + assertEquals(0, rl.getReadLockCount()); + ReentrantReadWriteLock r2 = new ReentrantReadWriteLock(true); + assertTrue(r2.isFair()); + assertFalse(r2.isWriteLocked()); + assertEquals(0, r2.getReadLockCount()); + } + + /** + * write-locking and read-locking an unlocked lock succeed + */ + public void testLock() { + ReentrantReadWriteLock rl = new ReentrantReadWriteLock(); + rl.writeLock().lock(); + assertTrue(rl.isWriteLocked()); + assertTrue(rl.isWriteLockedByCurrentThread()); + assertEquals(0, rl.getReadLockCount()); + rl.writeLock().unlock(); + assertFalse(rl.isWriteLocked()); + assertFalse(rl.isWriteLockedByCurrentThread()); + assertEquals(0, rl.getReadLockCount()); + rl.readLock().lock(); + assertFalse(rl.isWriteLocked()); + assertFalse(rl.isWriteLockedByCurrentThread()); + assertEquals(1, rl.getReadLockCount()); + rl.readLock().unlock(); + assertFalse(rl.isWriteLocked()); + assertFalse(rl.isWriteLockedByCurrentThread()); + assertEquals(0, rl.getReadLockCount()); + } + + + /** + * locking an unlocked fair lock succeeds + */ + public void testFairLock() { + ReentrantReadWriteLock rl = new ReentrantReadWriteLock(true); + rl.writeLock().lock(); + assertTrue(rl.isWriteLocked()); + assertTrue(rl.isWriteLockedByCurrentThread()); + assertEquals(0, rl.getReadLockCount()); + rl.writeLock().unlock(); + assertFalse(rl.isWriteLocked()); + assertFalse(rl.isWriteLockedByCurrentThread()); + assertEquals(0, rl.getReadLockCount()); + rl.readLock().lock(); + assertFalse(rl.isWriteLocked()); + assertFalse(rl.isWriteLockedByCurrentThread()); + assertEquals(1, rl.getReadLockCount()); + rl.readLock().unlock(); + assertFalse(rl.isWriteLocked()); + assertFalse(rl.isWriteLockedByCurrentThread()); + assertEquals(0, rl.getReadLockCount()); + } + + /** + * getWriteHoldCount returns number of recursive holds + */ + public void testGetHoldCount() { + ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + for(int i = 1; i <= SIZE; i++) { + lock.writeLock().lock(); + assertEquals(i,lock.getWriteHoldCount()); + } + for(int i = SIZE; i > 0; i--) { + lock.writeLock().unlock(); + assertEquals(i-1,lock.getWriteHoldCount()); + } + } + + + /** + * write-unlocking an unlocked lock throws IllegalMonitorStateException + */ + public void testUnlock_IllegalMonitorStateException() { + ReentrantReadWriteLock rl = new ReentrantReadWriteLock(); + try { + rl.writeLock().unlock(); + shouldThrow(); + } catch(IllegalMonitorStateException success){} + } + + + /** + * write-lockInterruptibly is interruptible + */ + public void testWriteLockInterruptibly_Interrupted() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + lock.writeLock().lockInterruptibly(); + lock.writeLock().unlock(); + lock.writeLock().lockInterruptibly(); + lock.writeLock().unlock(); + } catch(InterruptedException success){} + } + }); + try { + lock.writeLock().lock(); + t.start(); + t.interrupt(); + lock.writeLock().unlock(); + t.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * timed write-tryLock is interruptible + */ + public void testWriteTryLock_Interrupted() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + lock.writeLock().lock(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + lock.writeLock().tryLock(1000,TimeUnit.MILLISECONDS); + } catch(InterruptedException success){} + } + }); + try { + t.start(); + t.interrupt(); + lock.writeLock().unlock(); + t.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * read-lockInterruptibly is interruptible + */ + public void testReadLockInterruptibly_Interrupted() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + lock.writeLock().lock(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + lock.readLock().lockInterruptibly(); + } catch(InterruptedException success){} + } + }); + try { + t.start(); + t.interrupt(); + lock.writeLock().unlock(); + t.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * timed read-tryLock is interruptible + */ + public void testReadTryLock_Interrupted() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + lock.writeLock().lock(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + lock.readLock().tryLock(1000,TimeUnit.MILLISECONDS); + threadShouldThrow(); + } catch(InterruptedException success){} + } + }); + try { + t.start(); + t.interrupt(); + t.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + + /** + * write-tryLock fails if locked + */ + public void testWriteTryLockWhenLocked() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + lock.writeLock().lock(); + Thread t = new Thread(new Runnable() { + public void run() { + threadAssertFalse(lock.writeLock().tryLock()); + } + }); + try { + t.start(); + t.join(); + lock.writeLock().unlock(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * read-tryLock fails if locked + */ + public void testReadTryLockWhenLocked() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + lock.writeLock().lock(); + Thread t = new Thread(new Runnable() { + public void run() { + threadAssertFalse(lock.readLock().tryLock()); + } + }); + try { + t.start(); + t.join(); + lock.writeLock().unlock(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * Multiple threads can hold a read lock when not write-locked + */ + public void testMultipleReadLocks() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + lock.readLock().lock(); + Thread t = new Thread(new Runnable() { + public void run() { + threadAssertTrue(lock.readLock().tryLock()); + lock.readLock().unlock(); + } + }); + try { + t.start(); + t.join(); + lock.readLock().unlock(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * A writelock succeeds after reading threads unlock + */ + public void testWriteAfterMultipleReadLocks() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + lock.readLock().lock(); + Thread t1 = new Thread(new Runnable() { + public void run() { + lock.readLock().lock(); + lock.readLock().unlock(); + } + }); + Thread t2 = new Thread(new Runnable() { + public void run() { + lock.writeLock().lock(); + lock.writeLock().unlock(); + } + }); + + try { + t1.start(); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + lock.readLock().unlock(); + t1.join(MEDIUM_DELAY_MS); + t2.join(MEDIUM_DELAY_MS); + assertTrue(!t1.isAlive()); + assertTrue(!t2.isAlive()); + + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * Readlocks succeed after a writing thread unlocks + */ + public void testReadAfterWriteLock() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + lock.writeLock().lock(); + Thread t1 = new Thread(new Runnable() { + public void run() { + lock.readLock().lock(); + lock.readLock().unlock(); + } + }); + Thread t2 = new Thread(new Runnable() { + public void run() { + lock.readLock().lock(); + lock.readLock().unlock(); + } + }); + + try { + t1.start(); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + lock.writeLock().unlock(); + t1.join(MEDIUM_DELAY_MS); + t2.join(MEDIUM_DELAY_MS); + assertTrue(!t1.isAlive()); + assertTrue(!t2.isAlive()); + + } catch(Exception e){ + unexpectedException(); + } + } + + + /** + * Read tryLock succeeds if readlocked but not writelocked + */ + public void testTryLockWhenReadLocked() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + lock.readLock().lock(); + Thread t = new Thread(new Runnable() { + public void run() { + threadAssertTrue(lock.readLock().tryLock()); + lock.readLock().unlock(); + } + }); + try { + t.start(); + t.join(); + lock.readLock().unlock(); + } catch(Exception e){ + unexpectedException(); + } + } + + + + /** + * write tryLock fails when readlocked + */ + public void testWriteTryLockWhenReadLocked() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + lock.readLock().lock(); + Thread t = new Thread(new Runnable() { + public void run() { + threadAssertFalse(lock.writeLock().tryLock()); + } + }); + try { + t.start(); + t.join(); + lock.readLock().unlock(); + } catch(Exception e){ + unexpectedException(); + } + } + + + + /** + * write timed tryLock times out if locked + */ + public void testWriteTryLock_Timeout() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + lock.writeLock().lock(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + threadAssertFalse(lock.writeLock().tryLock(1, TimeUnit.MILLISECONDS)); + } catch (Exception ex) { + threadUnexpectedException(); + } + } + }); + try { + t.start(); + t.join(); + lock.writeLock().unlock(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * read timed tryLock times out if write-locked + */ + public void testReadTryLock_Timeout() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + lock.writeLock().lock(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + threadAssertFalse(lock.readLock().tryLock(1, TimeUnit.MILLISECONDS)); + } catch (Exception ex) { + threadUnexpectedException(); + } + } + }); + try { + t.start(); + t.join(); + lock.writeLock().unlock(); + } catch(Exception e){ + unexpectedException(); + } + } + + + /** + * write lockInterruptibly succeeds if lock free else is interruptible + */ + public void testWriteLockInterruptibly() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + try { + lock.writeLock().lockInterruptibly(); + } catch(Exception e) { + unexpectedException(); + } + Thread t = new Thread(new Runnable() { + public void run() { + try { + lock.writeLock().lockInterruptibly(); + threadShouldThrow(); + } + catch(InterruptedException success) { + } + } + }); + try { + t.start(); + t.interrupt(); + t.join(); + lock.writeLock().unlock(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * read lockInterruptibly succeeds if lock free else is interruptible + */ + public void testReadLockInterruptibly() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + try { + lock.writeLock().lockInterruptibly(); + } catch(Exception e) { + unexpectedException(); + } + Thread t = new Thread(new Runnable() { + public void run() { + try { + lock.readLock().lockInterruptibly(); + threadShouldThrow(); + } + catch(InterruptedException success) { + } + } + }); + try { + t.start(); + t.interrupt(); + t.join(); + lock.writeLock().unlock(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * Calling await without holding lock throws IllegalMonitorStateException + */ + public void testAwait_IllegalMonitor() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + final Condition c = lock.writeLock().newCondition(); + try { + c.await(); + shouldThrow(); + } + catch (IllegalMonitorStateException success) { + } + catch (Exception ex) { + shouldThrow(); + } + } + + /** + * Calling signal without holding lock throws IllegalMonitorStateException + */ + public void testSignal_IllegalMonitor() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + final Condition c = lock.writeLock().newCondition(); + try { + c.signal(); + shouldThrow(); + } + catch (IllegalMonitorStateException success) { + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * awaitNanos without a signal times out + */ + public void testAwaitNanos_Timeout() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + final Condition c = lock.writeLock().newCondition(); + try { + lock.writeLock().lock(); + long t = c.awaitNanos(100); + assertTrue(t <= 0); + lock.writeLock().unlock(); + } + catch (Exception ex) { + unexpectedException(); + } + } + + + /** + * timed await without a signal times out + */ + public void testAwait_Timeout() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + final Condition c = lock.writeLock().newCondition(); + try { + lock.writeLock().lock(); + assertFalse(c.await(10, TimeUnit.MILLISECONDS)); + lock.writeLock().unlock(); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * awaitUntil without a signal times out + */ + public void testAwaitUntil_Timeout() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + final Condition c = lock.writeLock().newCondition(); + try { + lock.writeLock().lock(); + java.util.Date d = new java.util.Date(); + assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10))); + lock.writeLock().unlock(); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * await returns when signalled + */ + public void testAwait() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + final Condition c = lock.writeLock().newCondition(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + lock.writeLock().lock(); + c.await(); + lock.writeLock().unlock(); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + lock.writeLock().lock(); + c.signal(); + lock.writeLock().unlock(); + t.join(SHORT_DELAY_MS); + assertFalse(t.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * awaitUninterruptibly doesn't abort on interrupt + */ + public void testAwaitUninterruptibly() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + final Condition c = lock.writeLock().newCondition(); + Thread t = new Thread(new Runnable() { + public void run() { + lock.writeLock().lock(); + c.awaitUninterruptibly(); + lock.writeLock().unlock(); + } + }); + + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + lock.writeLock().lock(); + c.signal(); + lock.writeLock().unlock(); + assert(t.isInterrupted()); + t.join(SHORT_DELAY_MS); + assertFalse(t.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * await is interruptible + */ + public void testAwait_Interrupt() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + final Condition c = lock.writeLock().newCondition(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + lock.writeLock().lock(); + c.await(); + lock.writeLock().unlock(); + threadShouldThrow(); + } + catch(InterruptedException success) { + } + } + }); + + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(SHORT_DELAY_MS); + assertFalse(t.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * awaitNanos is interruptible + */ + public void testAwaitNanos_Interrupt() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + final Condition c = lock.writeLock().newCondition(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + lock.writeLock().lock(); + c.awaitNanos(SHORT_DELAY_MS * 2 * 1000000); + lock.writeLock().unlock(); + threadShouldThrow(); + } + catch(InterruptedException success) { + } + } + }); + + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(SHORT_DELAY_MS); + assertFalse(t.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * awaitUntil is interruptible + */ + public void testAwaitUntil_Interrupt() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + final Condition c = lock.writeLock().newCondition(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + lock.writeLock().lock(); + java.util.Date d = new java.util.Date(); + c.awaitUntil(new java.util.Date(d.getTime() + 10000)); + lock.writeLock().unlock(); + threadShouldThrow(); + } + catch(InterruptedException success) { + } + } + }); + + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(SHORT_DELAY_MS); + assertFalse(t.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * signalAll wakes up all threads + */ + public void testSignalAll() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + final Condition c = lock.writeLock().newCondition(); + Thread t1 = new Thread(new Runnable() { + public void run() { + try { + lock.writeLock().lock(); + c.await(); + lock.writeLock().unlock(); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + Thread t2 = new Thread(new Runnable() { + public void run() { + try { + lock.writeLock().lock(); + c.await(); + lock.writeLock().unlock(); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + try { + t1.start(); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + lock.writeLock().lock(); + c.signalAll(); + lock.writeLock().unlock(); + t1.join(SHORT_DELAY_MS); + t2.join(SHORT_DELAY_MS); + assertFalse(t1.isAlive()); + assertFalse(t2.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * A serialized lock deserializes as unlocked + */ + public void testSerialization() { + ReentrantReadWriteLock l = new ReentrantReadWriteLock(); + l.readLock().lock(); + l.readLock().unlock(); + + try { + ByteArrayOutputStream bout = new ByteArrayOutputStream(10000); + ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout)); + out.writeObject(l); + out.close(); + + ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); + ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin)); + ReentrantReadWriteLock r = (ReentrantReadWriteLock) in.readObject(); + r.readLock().lock(); + r.readLock().unlock(); + } catch(Exception e){ + e.printStackTrace(); + unexpectedException(); + } + } + + /** + * hasQueuedThreads reports whether there are waiting threads + */ + public void testhasQueuedThreads() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + Thread t1 = new Thread(new InterruptedLockRunnable(lock)); + Thread t2 = new Thread(new InterruptibleLockRunnable(lock)); + try { + assertFalse(lock.hasQueuedThreads()); + lock.writeLock().lock(); + t1.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(lock.hasQueuedThreads()); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(lock.hasQueuedThreads()); + t1.interrupt(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(lock.hasQueuedThreads()); + lock.writeLock().unlock(); + Thread.sleep(SHORT_DELAY_MS); + assertFalse(lock.hasQueuedThreads()); + t1.join(); + t2.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * hasQueuedThread(null) throws NPE + */ + public void testHasQueuedThreadNPE() { + final ReentrantReadWriteLock sync = new ReentrantReadWriteLock(); + try { + sync.hasQueuedThread(null); + shouldThrow(); + } catch (NullPointerException success) { + } + } + + /** + * hasQueuedThread reports whether a thread is queued. + */ + public void testHasQueuedThread() { + final ReentrantReadWriteLock sync = new ReentrantReadWriteLock(); + Thread t1 = new Thread(new InterruptedLockRunnable(sync)); + Thread t2 = new Thread(new InterruptibleLockRunnable(sync)); + try { + assertFalse(sync.hasQueuedThread(t1)); + assertFalse(sync.hasQueuedThread(t2)); + sync.writeLock().lock(); + t1.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(sync.hasQueuedThread(t1)); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(sync.hasQueuedThread(t1)); + assertTrue(sync.hasQueuedThread(t2)); + t1.interrupt(); + Thread.sleep(SHORT_DELAY_MS); + assertFalse(sync.hasQueuedThread(t1)); + assertTrue(sync.hasQueuedThread(t2)); + sync.writeLock().unlock(); + Thread.sleep(SHORT_DELAY_MS); + assertFalse(sync.hasQueuedThread(t1)); + Thread.sleep(SHORT_DELAY_MS); + assertFalse(sync.hasQueuedThread(t2)); + t1.join(); + t2.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + + /** + * getQueueLength reports number of waiting threads + */ + public void testGetQueueLength() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + Thread t1 = new Thread(new InterruptedLockRunnable(lock)); + Thread t2 = new Thread(new InterruptibleLockRunnable(lock)); + try { + assertEquals(0, lock.getQueueLength()); + lock.writeLock().lock(); + t1.start(); + Thread.sleep(SHORT_DELAY_MS); + assertEquals(1, lock.getQueueLength()); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + assertEquals(2, lock.getQueueLength()); + t1.interrupt(); + Thread.sleep(SHORT_DELAY_MS); + assertEquals(1, lock.getQueueLength()); + lock.writeLock().unlock(); + Thread.sleep(SHORT_DELAY_MS); + assertEquals(0, lock.getQueueLength()); + t1.join(); + t2.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * getQueuedThreads includes waiting threads + */ + public void testGetQueuedThreads() { + final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock(); + Thread t1 = new Thread(new InterruptedLockRunnable(lock)); + Thread t2 = new Thread(new InterruptibleLockRunnable(lock)); + try { + assertTrue(lock.getQueuedThreads().isEmpty()); + lock.writeLock().lock(); + assertTrue(lock.getQueuedThreads().isEmpty()); + t1.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(lock.getQueuedThreads().contains(t1)); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(lock.getQueuedThreads().contains(t1)); + assertTrue(lock.getQueuedThreads().contains(t2)); + t1.interrupt(); + Thread.sleep(SHORT_DELAY_MS); + assertFalse(lock.getQueuedThreads().contains(t1)); + assertTrue(lock.getQueuedThreads().contains(t2)); + lock.writeLock().unlock(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(lock.getQueuedThreads().isEmpty()); + t1.join(); + t2.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * hasWaiters throws NPE if null + */ + public void testHasWaitersNPE() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + try { + lock.hasWaiters(null); + shouldThrow(); + } catch (NullPointerException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + /** + * getWaitQueueLength throws NPE if null + */ + public void testGetWaitQueueLengthNPE() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + try { + lock.getWaitQueueLength(null); + shouldThrow(); + } catch (NullPointerException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + + /** + * getWaitingThreads throws NPE if null + */ + public void testGetWaitingThreadsNPE() { + final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock(); + try { + lock.getWaitingThreads(null); + shouldThrow(); + } catch (NullPointerException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + /** + * hasWaiters throws IAE if not owned + */ + public void testHasWaitersIAE() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + final Condition c = (lock.writeLock().newCondition()); + final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock(); + try { + lock2.hasWaiters(c); + shouldThrow(); + } catch (IllegalArgumentException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + /** + * hasWaiters throws IMSE if not locked + */ + public void testHasWaitersIMSE() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + final Condition c = (lock.writeLock().newCondition()); + try { + lock.hasWaiters(c); + shouldThrow(); + } catch (IllegalMonitorStateException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + + /** + * getWaitQueueLength throws IAE if not owned + */ + public void testGetWaitQueueLengthIAE() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + final Condition c = (lock.writeLock().newCondition()); + final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock(); + try { + lock2.getWaitQueueLength(c); + shouldThrow(); + } catch (IllegalArgumentException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + /** + * getWaitQueueLength throws IMSE if not locked + */ + public void testGetWaitQueueLengthIMSE() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + final Condition c = (lock.writeLock().newCondition()); + try { + lock.getWaitQueueLength(c); + shouldThrow(); + } catch (IllegalMonitorStateException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + + /** + * getWaitingThreads throws IAE if not owned + */ + public void testGetWaitingThreadsIAE() { + final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock(); + final Condition c = (lock.writeLock().newCondition()); + final PublicReentrantReadWriteLock lock2 = new PublicReentrantReadWriteLock(); + try { + lock2.getWaitingThreads(c); + shouldThrow(); + } catch (IllegalArgumentException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + /** + * getWaitingThreads throws IMSE if not locked + */ + public void testGetWaitingThreadsIMSE() { + final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock(); + final Condition c = (lock.writeLock().newCondition()); + try { + lock.getWaitingThreads(c); + shouldThrow(); + } catch (IllegalMonitorStateException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + + /** + * hasWaiters returns true when a thread is waiting, else false + */ + public void testHasWaiters() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + final Condition c = (lock.writeLock().newCondition()); + Thread t = new Thread(new Runnable() { + public void run() { + try { + lock.writeLock().lock(); + threadAssertFalse(lock.hasWaiters(c)); + threadAssertEquals(0, lock.getWaitQueueLength(c)); + c.await(); + lock.writeLock().unlock(); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + lock.writeLock().lock(); + assertTrue(lock.hasWaiters(c)); + assertEquals(1, lock.getWaitQueueLength(c)); + c.signal(); + lock.writeLock().unlock(); + Thread.sleep(SHORT_DELAY_MS); + lock.writeLock().lock(); + assertFalse(lock.hasWaiters(c)); + assertEquals(0, lock.getWaitQueueLength(c)); + lock.writeLock().unlock(); + t.join(SHORT_DELAY_MS); + assertFalse(t.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * getWaitQueueLength returns number of waiting threads + */ + public void testGetWaitQueueLength() { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + final Condition c = (lock.writeLock().newCondition()); + Thread t = new Thread(new Runnable() { + public void run() { + try { + lock.writeLock().lock(); + threadAssertFalse(lock.hasWaiters(c)); + threadAssertEquals(0, lock.getWaitQueueLength(c)); + c.await(); + lock.writeLock().unlock(); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + lock.writeLock().lock(); + assertTrue(lock.hasWaiters(c)); + assertEquals(1, lock.getWaitQueueLength(c)); + c.signal(); + lock.writeLock().unlock(); + Thread.sleep(SHORT_DELAY_MS); + lock.writeLock().lock(); + assertFalse(lock.hasWaiters(c)); + assertEquals(0, lock.getWaitQueueLength(c)); + lock.writeLock().unlock(); + t.join(SHORT_DELAY_MS); + assertFalse(t.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + + /** + * getWaitingThreads returns only and all waiting threads + */ + public void testGetWaitingThreads() { + final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock(); + final Condition c = lock.writeLock().newCondition(); + Thread t1 = new Thread(new Runnable() { + public void run() { + try { + lock.writeLock().lock(); + threadAssertTrue(lock.getWaitingThreads(c).isEmpty()); + c.await(); + lock.writeLock().unlock(); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + Thread t2 = new Thread(new Runnable() { + public void run() { + try { + lock.writeLock().lock(); + threadAssertFalse(lock.getWaitingThreads(c).isEmpty()); + c.await(); + lock.writeLock().unlock(); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + try { + lock.writeLock().lock(); + assertTrue(lock.getWaitingThreads(c).isEmpty()); + lock.writeLock().unlock(); + t1.start(); + Thread.sleep(SHORT_DELAY_MS); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + lock.writeLock().lock(); + assertTrue(lock.hasWaiters(c)); + assertTrue(lock.getWaitingThreads(c).contains(t1)); + assertTrue(lock.getWaitingThreads(c).contains(t2)); + c.signalAll(); + lock.writeLock().unlock(); + Thread.sleep(SHORT_DELAY_MS); + lock.writeLock().lock(); + assertFalse(lock.hasWaiters(c)); + assertTrue(lock.getWaitingThreads(c).isEmpty()); + lock.writeLock().unlock(); + t1.join(SHORT_DELAY_MS); + t2.join(SHORT_DELAY_MS); + assertFalse(t1.isAlive()); + assertFalse(t2.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * toString indicates current lock state + */ + public void testToString() { + ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + String us = lock.toString(); + assertTrue(us.indexOf("Write locks = 0") >= 0); + assertTrue(us.indexOf("Read locks = 0") >= 0); + lock.writeLock().lock(); + String ws = lock.toString(); + assertTrue(ws.indexOf("Write locks = 1") >= 0); + assertTrue(ws.indexOf("Read locks = 0") >= 0); + lock.writeLock().unlock(); + lock.readLock().lock(); + lock.readLock().lock(); + String rs = lock.toString(); + assertTrue(rs.indexOf("Write locks = 0") >= 0); + assertTrue(rs.indexOf("Read locks = 2") >= 0); + } + + /** + * readLock.toString indicates current lock state + */ + public void testReadLockToString() { + ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + String us = lock.readLock().toString(); + assertTrue(us.indexOf("Read locks = 0") >= 0); + lock.readLock().lock(); + lock.readLock().lock(); + String rs = lock.readLock().toString(); + assertTrue(rs.indexOf("Read locks = 2") >= 0); + } + + /** + * writeLock.toString indicates current lock state + */ + public void testWriteLockToString() { + ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + String us = lock.writeLock().toString(); + assertTrue(us.indexOf("Unlocked") >= 0); + lock.writeLock().lock(); + String ls = lock.writeLock().toString(); + assertTrue(ls.indexOf("Locked") >= 0); + } + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ScheduledExecutorTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ScheduledExecutorTest.java new file mode 100755 index 0000000..da5704e --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ScheduledExecutorTest.java @@ -0,0 +1,1149 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.*; + +public class ScheduledExecutorTest extends JSR166TestCase { + public static void main(String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(ScheduledExecutorTest.class); + } + + + /** + * execute successfully executes a runnable + */ + public void testExecute() { + try { + TrackedShortRunnable runnable =new TrackedShortRunnable(); + ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1); + p1.execute(runnable); + assertFalse(runnable.done); + Thread.sleep(SHORT_DELAY_MS); + try { p1.shutdown(); } catch(SecurityException ok) { return; } + try { + Thread.sleep(MEDIUM_DELAY_MS); + } catch(InterruptedException e){ + unexpectedException(); + } + assertTrue(runnable.done); + try { p1.shutdown(); } catch(SecurityException ok) { return; } + joinPool(p1); + } + catch(Exception e){ + unexpectedException(); + } + + } + + + /** + * delayed schedule of callable successfully executes after delay + */ + public void testSchedule1() { + try { + TrackedCallable callable = new TrackedCallable(); + ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1); + Future f = p1.schedule(callable, SHORT_DELAY_MS, TimeUnit.MILLISECONDS); + assertFalse(callable.done); + Thread.sleep(MEDIUM_DELAY_MS); + assertTrue(callable.done); + assertEquals(Boolean.TRUE, f.get()); + try { p1.shutdown(); } catch(SecurityException ok) { return; } + joinPool(p1); + } catch(RejectedExecutionException e){} + catch(Exception e){ + e.printStackTrace(); + unexpectedException(); + } + } + + /** + * delayed schedule of runnable successfully executes after delay + */ + public void testSchedule3() { + try { + TrackedShortRunnable runnable = new TrackedShortRunnable(); + ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1); + p1.schedule(runnable, SMALL_DELAY_MS, TimeUnit.MILLISECONDS); + Thread.sleep(SHORT_DELAY_MS); + assertFalse(runnable.done); + Thread.sleep(MEDIUM_DELAY_MS); + assertTrue(runnable.done); + try { p1.shutdown(); } catch(SecurityException ok) { return; } + joinPool(p1); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * scheduleAtFixedRate executes runnable after given initial delay + */ + public void testSchedule4() { + try { + TrackedShortRunnable runnable = new TrackedShortRunnable(); + ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1); + ScheduledFuture h = p1.scheduleAtFixedRate(runnable, SHORT_DELAY_MS, SHORT_DELAY_MS, TimeUnit.MILLISECONDS); + assertFalse(runnable.done); + Thread.sleep(MEDIUM_DELAY_MS); + assertTrue(runnable.done); + h.cancel(true); + joinPool(p1); + } catch(Exception e){ + unexpectedException(); + } + } + + static class RunnableCounter implements Runnable { + AtomicInteger count = new AtomicInteger(0); + public void run() { count.getAndIncrement(); } + } + + /** + * scheduleWithFixedDelay executes runnable after given initial delay + */ + public void testSchedule5() { + try { + TrackedShortRunnable runnable = new TrackedShortRunnable(); + ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1); + ScheduledFuture h = p1.scheduleWithFixedDelay(runnable, SHORT_DELAY_MS, SHORT_DELAY_MS, TimeUnit.MILLISECONDS); + assertFalse(runnable.done); + Thread.sleep(MEDIUM_DELAY_MS); + assertTrue(runnable.done); + h.cancel(true); + joinPool(p1); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * scheduleAtFixedRate executes series of tasks at given rate + */ + public void testFixedRateSequence() { + try { + ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1); + RunnableCounter counter = new RunnableCounter(); + ScheduledFuture h = + p1.scheduleAtFixedRate(counter, 0, 1, TimeUnit.MILLISECONDS); + Thread.sleep(SMALL_DELAY_MS); + h.cancel(true); + int c = counter.count.get(); + // By time scaling conventions, we must have at least + // an execution per SHORT delay, but no more than one SHORT more + assertTrue(c >= SMALL_DELAY_MS / SHORT_DELAY_MS); + assertTrue(c <= SMALL_DELAY_MS + SHORT_DELAY_MS); + joinPool(p1); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * scheduleWithFixedDelay executes series of tasks with given period + */ + public void testFixedDelaySequence() { + try { + ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1); + RunnableCounter counter = new RunnableCounter(); + ScheduledFuture h = + p1.scheduleWithFixedDelay(counter, 0, 1, TimeUnit.MILLISECONDS); + Thread.sleep(SMALL_DELAY_MS); + h.cancel(true); + int c = counter.count.get(); + assertTrue(c >= SMALL_DELAY_MS / SHORT_DELAY_MS); + assertTrue(c <= SMALL_DELAY_MS + SHORT_DELAY_MS); + joinPool(p1); + } catch(Exception e){ + unexpectedException(); + } + } + + + /** + * execute (null) throws NPE + */ + public void testExecuteNull() { + ScheduledThreadPoolExecutor se = null; + try { + se = new ScheduledThreadPoolExecutor(1); + se.execute(null); + shouldThrow(); + } catch(NullPointerException success){} + catch(Exception e){ + unexpectedException(); + } + + joinPool(se); + } + + /** + * schedule (null) throws NPE + */ + public void testScheduleNull() { + ScheduledThreadPoolExecutor se = new ScheduledThreadPoolExecutor(1); + try { + TrackedCallable callable = null; + Future f = se.schedule(callable, SHORT_DELAY_MS, TimeUnit.MILLISECONDS); + shouldThrow(); + } catch(NullPointerException success){} + catch(Exception e){ + unexpectedException(); + } + joinPool(se); + } + + /** + * execute throws RejectedExecutionException if shutdown + */ + public void testSchedule1_RejectedExecutionException() { + ScheduledThreadPoolExecutor se = new ScheduledThreadPoolExecutor(1); + try { + se.shutdown(); + se.schedule(new NoOpRunnable(), + MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + shouldThrow(); + } catch(RejectedExecutionException success){ + } catch (SecurityException ok) { + } + + joinPool(se); + + } + + /** + * schedule throws RejectedExecutionException if shutdown + */ + public void testSchedule2_RejectedExecutionException() { + ScheduledThreadPoolExecutor se = new ScheduledThreadPoolExecutor(1); + try { + se.shutdown(); + se.schedule(new NoOpCallable(), + MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + shouldThrow(); + } catch(RejectedExecutionException success){ + } catch (SecurityException ok) { + } + joinPool(se); + } + + /** + * schedule callable throws RejectedExecutionException if shutdown + */ + public void testSchedule3_RejectedExecutionException() { + ScheduledThreadPoolExecutor se = new ScheduledThreadPoolExecutor(1); + try { + se.shutdown(); + se.schedule(new NoOpCallable(), + MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + shouldThrow(); + } catch(RejectedExecutionException success){ + } catch (SecurityException ok) { + } + joinPool(se); + } + + /** + * scheduleAtFixedRate throws RejectedExecutionException if shutdown + */ + public void testScheduleAtFixedRate1_RejectedExecutionException() { + ScheduledThreadPoolExecutor se = new ScheduledThreadPoolExecutor(1); + try { + se.shutdown(); + se.scheduleAtFixedRate(new NoOpRunnable(), + MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + shouldThrow(); + } catch(RejectedExecutionException success){ + } catch (SecurityException ok) { + } + joinPool(se); + } + + /** + * scheduleWithFixedDelay throws RejectedExecutionException if shutdown + */ + public void testScheduleWithFixedDelay1_RejectedExecutionException() { + ScheduledThreadPoolExecutor se = new ScheduledThreadPoolExecutor(1); + try { + se.shutdown(); + se.scheduleWithFixedDelay(new NoOpRunnable(), + MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + shouldThrow(); + } catch(RejectedExecutionException success){ + } catch (SecurityException ok) { + } + joinPool(se); + } + + /** + * getActiveCount increases but doesn't overestimate, when a + * thread becomes active + */ + public void testGetActiveCount() { + ScheduledThreadPoolExecutor p2 = new ScheduledThreadPoolExecutor(2); + assertEquals(0, p2.getActiveCount()); + p2.execute(new SmallRunnable()); + try { + Thread.sleep(SHORT_DELAY_MS); + } catch(Exception e){ + unexpectedException(); + } + assertEquals(1, p2.getActiveCount()); + joinPool(p2); + } + + /** + * getCompletedTaskCount increases, but doesn't overestimate, + * when tasks complete + */ + public void testGetCompletedTaskCount() { + ScheduledThreadPoolExecutor p2 = new ScheduledThreadPoolExecutor(2); + assertEquals(0, p2.getCompletedTaskCount()); + p2.execute(new SmallRunnable()); + try { + Thread.sleep(MEDIUM_DELAY_MS); + } catch(Exception e){ + unexpectedException(); + } + assertEquals(1, p2.getCompletedTaskCount()); + joinPool(p2); + } + + /** + * getCorePoolSize returns size given in constructor if not otherwise set + */ + public void testGetCorePoolSize() { + ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1); + assertEquals(1, p1.getCorePoolSize()); + joinPool(p1); + } + + /** + * getLargestPoolSize increases, but doesn't overestimate, when + * multiple threads active + */ + public void testGetLargestPoolSize() { + ScheduledThreadPoolExecutor p2 = new ScheduledThreadPoolExecutor(2); + assertEquals(0, p2.getLargestPoolSize()); + p2.execute(new SmallRunnable()); + p2.execute(new SmallRunnable()); + try { + Thread.sleep(SHORT_DELAY_MS); + } catch(Exception e){ + unexpectedException(); + } + assertEquals(2, p2.getLargestPoolSize()); + joinPool(p2); + } + + /** + * getPoolSize increases, but doesn't overestimate, when threads + * become active + */ + public void testGetPoolSize() { + ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1); + assertEquals(0, p1.getPoolSize()); + p1.execute(new SmallRunnable()); + assertEquals(1, p1.getPoolSize()); + joinPool(p1); + } + + /** + * getTaskCount increases, but doesn't overestimate, when tasks + * submitted + */ + public void testGetTaskCount() { + ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1); + assertEquals(0, p1.getTaskCount()); + for(int i = 0; i < 5; i++) + p1.execute(new SmallRunnable()); + try { + Thread.sleep(SHORT_DELAY_MS); + } catch(Exception e){ + unexpectedException(); + } + assertEquals(5, p1.getTaskCount()); + joinPool(p1); + } + + /** + * getThreadFactory returns factory in constructor if not set + */ + public void testGetThreadFactory() { + ThreadFactory tf = new SimpleThreadFactory(); + ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1, tf); + assertSame(tf, p.getThreadFactory()); + joinPool(p); + } + + /** + * setThreadFactory sets the thread factory returned by getThreadFactory + */ + public void testSetThreadFactory() { + ThreadFactory tf = new SimpleThreadFactory(); + ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1); + p.setThreadFactory(tf); + assertSame(tf, p.getThreadFactory()); + joinPool(p); + } + + /** + * setThreadFactory(null) throws NPE + */ + public void testSetThreadFactoryNull() { + ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1); + try { + p.setThreadFactory(null); + shouldThrow(); + } catch (NullPointerException success) { + } finally { + joinPool(p); + } + } + + /** + * is isShutDown is false before shutdown, true after + */ + public void testIsShutdown() { + + ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1); + try { + assertFalse(p1.isShutdown()); + } + finally { + try { p1.shutdown(); } catch(SecurityException ok) { return; } + } + assertTrue(p1.isShutdown()); + } + + + /** + * isTerminated is false before termination, true after + */ + public void testIsTerminated() { + ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1); + try { + p1.execute(new SmallRunnable()); + } finally { + try { p1.shutdown(); } catch(SecurityException ok) { return; } + } + try { + assertTrue(p1.awaitTermination(LONG_DELAY_MS, TimeUnit.MILLISECONDS)); + assertTrue(p1.isTerminated()); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * isTerminating is not true when running or when terminated + */ + public void testIsTerminating() { + ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1); + assertFalse(p1.isTerminating()); + try { + p1.execute(new SmallRunnable()); + assertFalse(p1.isTerminating()); + } finally { + try { p1.shutdown(); } catch(SecurityException ok) { return; } + } + try { + assertTrue(p1.awaitTermination(LONG_DELAY_MS, TimeUnit.MILLISECONDS)); + assertTrue(p1.isTerminated()); + assertFalse(p1.isTerminating()); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * getQueue returns the work queue, which contains queued tasks + */ + public void testGetQueue() { + ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1); + ScheduledFuture[] tasks = new ScheduledFuture[5]; + for(int i = 0; i < 5; i++){ + tasks[i] = p1.schedule(new SmallPossiblyInterruptedRunnable(), 1, TimeUnit.MILLISECONDS); + } + try { + Thread.sleep(SHORT_DELAY_MS); + BlockingQueue<Runnable> q = p1.getQueue(); + assertTrue(q.contains(tasks[4])); + assertFalse(q.contains(tasks[0])); + } catch(Exception e) { + unexpectedException(); + } finally { + joinPool(p1); + } + } + + /** + * remove(task) removes queued task, and fails to remove active task + */ + public void testRemove() { + ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1); + ScheduledFuture[] tasks = new ScheduledFuture[5]; + for(int i = 0; i < 5; i++){ + tasks[i] = p1.schedule(new SmallPossiblyInterruptedRunnable(), 1, TimeUnit.MILLISECONDS); + } + try { + Thread.sleep(SHORT_DELAY_MS); + BlockingQueue<Runnable> q = p1.getQueue(); + assertFalse(p1.remove((Runnable)tasks[0])); + assertTrue(q.contains((Runnable)tasks[4])); + assertTrue(q.contains((Runnable)tasks[3])); + assertTrue(p1.remove((Runnable)tasks[4])); + assertFalse(p1.remove((Runnable)tasks[4])); + assertFalse(q.contains((Runnable)tasks[4])); + assertTrue(q.contains((Runnable)tasks[3])); + assertTrue(p1.remove((Runnable)tasks[3])); + assertFalse(q.contains((Runnable)tasks[3])); + } catch(Exception e) { + unexpectedException(); + } finally { + joinPool(p1); + } + } + + /** + * purge removes cancelled tasks from the queue + */ + public void testPurge() { + ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1); + ScheduledFuture[] tasks = new ScheduledFuture[5]; + for(int i = 0; i < 5; i++){ + tasks[i] = p1.schedule(new SmallPossiblyInterruptedRunnable(), SHORT_DELAY_MS, TimeUnit.MILLISECONDS); + } + try { + int max = 5; + if (tasks[4].cancel(true)) --max; + if (tasks[3].cancel(true)) --max; + // There must eventually be an interference-free point at + // which purge will not fail. (At worst, when queue is empty.) + int k; + for (k = 0; k < SMALL_DELAY_MS; ++k) { + p1.purge(); + long count = p1.getTaskCount(); + if (count >= 0 && count <= max) + break; + Thread.sleep(1); + } + assertTrue(k < SMALL_DELAY_MS); + } catch(Exception e) { + unexpectedException(); + } finally { + joinPool(p1); + } + } + + /** + * shutDownNow returns a list containing tasks that were not run + */ + public void testShutDownNow() { + ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1); + for(int i = 0; i < 5; i++) + p1.schedule(new SmallPossiblyInterruptedRunnable(), SHORT_DELAY_MS, TimeUnit.MILLISECONDS); + List l; + try { + l = p1.shutdownNow(); + } catch (SecurityException ok) { + return; + } + assertTrue(p1.isShutdown()); + assertTrue(l.size() > 0 && l.size() <= 5); + joinPool(p1); + } + + /** + * In default setting, shutdown cancels periodic but not delayed + * tasks at shutdown + */ + public void testShutDown1() { + try { + ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1); + assertTrue(p1.getExecuteExistingDelayedTasksAfterShutdownPolicy()); + assertFalse(p1.getContinueExistingPeriodicTasksAfterShutdownPolicy()); + + ScheduledFuture[] tasks = new ScheduledFuture[5]; + for(int i = 0; i < 5; i++) + tasks[i] = p1.schedule(new NoOpRunnable(), SHORT_DELAY_MS, TimeUnit.MILLISECONDS); + try { p1.shutdown(); } catch(SecurityException ok) { return; } + BlockingQueue q = p1.getQueue(); + for (Iterator it = q.iterator(); it.hasNext();) { + ScheduledFuture t = (ScheduledFuture)it.next(); + assertFalse(t.isCancelled()); + } + assertTrue(p1.isShutdown()); + Thread.sleep(SMALL_DELAY_MS); + for (int i = 0; i < 5; ++i) { + assertTrue(tasks[i].isDone()); + assertFalse(tasks[i].isCancelled()); + } + + } + catch(Exception ex) { + unexpectedException(); + } + } + + + /** + * If setExecuteExistingDelayedTasksAfterShutdownPolicy is false, + * delayed tasks are cancelled at shutdown + */ + public void testShutDown2() { + try { + ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1); + p1.setExecuteExistingDelayedTasksAfterShutdownPolicy(false); + ScheduledFuture[] tasks = new ScheduledFuture[5]; + for(int i = 0; i < 5; i++) + tasks[i] = p1.schedule(new NoOpRunnable(), SHORT_DELAY_MS, TimeUnit.MILLISECONDS); + try { p1.shutdown(); } catch(SecurityException ok) { return; } + assertTrue(p1.isShutdown()); + BlockingQueue q = p1.getQueue(); + assertTrue(q.isEmpty()); + Thread.sleep(SMALL_DELAY_MS); + assertTrue(p1.isTerminated()); + } + catch(Exception ex) { + unexpectedException(); + } + } + + + /** + * If setContinueExistingPeriodicTasksAfterShutdownPolicy is set false, + * periodic tasks are not cancelled at shutdown + */ + public void testShutDown3() { + try { + ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1); + p1.setContinueExistingPeriodicTasksAfterShutdownPolicy(false); + ScheduledFuture task = + p1.scheduleAtFixedRate(new NoOpRunnable(), 5, 5, TimeUnit.MILLISECONDS); + try { p1.shutdown(); } catch(SecurityException ok) { return; } + assertTrue(p1.isShutdown()); + BlockingQueue q = p1.getQueue(); + assertTrue(q.isEmpty()); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(p1.isTerminated()); + } + catch(Exception ex) { + unexpectedException(); + } + } + + /** + * if setContinueExistingPeriodicTasksAfterShutdownPolicy is true, + * periodic tasks are cancelled at shutdown + */ + public void testShutDown4() { + ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1); + try { + p1.setContinueExistingPeriodicTasksAfterShutdownPolicy(true); + ScheduledFuture task = + p1.scheduleAtFixedRate(new NoOpRunnable(), 1, 1, TimeUnit.MILLISECONDS); + assertFalse(task.isCancelled()); + try { p1.shutdown(); } catch(SecurityException ok) { return; } + assertFalse(task.isCancelled()); + assertFalse(p1.isTerminated()); + assertTrue(p1.isShutdown()); + Thread.sleep(SHORT_DELAY_MS); + assertFalse(task.isCancelled()); + assertTrue(task.cancel(true)); + assertTrue(task.isDone()); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(p1.isTerminated()); + } + catch(Exception ex) { + unexpectedException(); + } + finally { + joinPool(p1); + } + } + + /** + * completed submit of callable returns result + */ + public void testSubmitCallable() { + ExecutorService e = new ScheduledThreadPoolExecutor(2); + try { + Future<String> future = e.submit(new StringTask()); + String result = future.get(); + assertSame(TEST_STRING, result); + } + catch (ExecutionException ex) { + unexpectedException(); + } + catch (InterruptedException ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * completed submit of runnable returns successfully + */ + public void testSubmitRunnable() { + ExecutorService e = new ScheduledThreadPoolExecutor(2); + try { + Future<?> future = e.submit(new NoOpRunnable()); + future.get(); + assertTrue(future.isDone()); + } + catch (ExecutionException ex) { + unexpectedException(); + } + catch (InterruptedException ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * completed submit of (runnable, result) returns result + */ + public void testSubmitRunnable2() { + ExecutorService e = new ScheduledThreadPoolExecutor(2); + try { + Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING); + String result = future.get(); + assertSame(TEST_STRING, result); + } + catch (ExecutionException ex) { + unexpectedException(); + } + catch (InterruptedException ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * invokeAny(null) throws NPE + */ + public void testInvokeAny1() { + ExecutorService e = new ScheduledThreadPoolExecutor(2); + try { + e.invokeAny(null); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * invokeAny(empty collection) throws IAE + */ + public void testInvokeAny2() { + ExecutorService e = new ScheduledThreadPoolExecutor(2); + try { + e.invokeAny(new ArrayList<Callable<String>>()); + } catch (IllegalArgumentException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * invokeAny(c) throws NPE if c has null elements + */ + public void testInvokeAny3() { + ExecutorService e = new ScheduledThreadPoolExecutor(2); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + l.add(null); + e.invokeAny(l); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * invokeAny(c) throws ExecutionException if no task completes + */ + public void testInvokeAny4() { + ExecutorService e = new ScheduledThreadPoolExecutor(2); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new NPETask()); + e.invokeAny(l); + } catch (ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * invokeAny(c) returns result of some task + */ + public void testInvokeAny5() { + ExecutorService e = new ScheduledThreadPoolExecutor(2); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + l.add(new StringTask()); + String result = e.invokeAny(l); + assertSame(TEST_STRING, result); + } catch (ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * invokeAll(null) throws NPE + */ + public void testInvokeAll1() { + ExecutorService e = new ScheduledThreadPoolExecutor(2); + try { + e.invokeAll(null); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * invokeAll(empty collection) returns empty collection + */ + public void testInvokeAll2() { + ExecutorService e = new ScheduledThreadPoolExecutor(2); + try { + List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>()); + assertTrue(r.isEmpty()); + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * invokeAll(c) throws NPE if c has null elements + */ + public void testInvokeAll3() { + ExecutorService e = new ScheduledThreadPoolExecutor(2); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + l.add(null); + e.invokeAll(l); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * get of invokeAll(c) throws exception on failed task + */ + public void testInvokeAll4() { + ExecutorService e = new ScheduledThreadPoolExecutor(2); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new NPETask()); + List<Future<String>> result = e.invokeAll(l); + assertEquals(1, result.size()); + for (Iterator<Future<String>> it = result.iterator(); it.hasNext();) + it.next().get(); + } catch(ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * invokeAll(c) returns results of all completed tasks + */ + public void testInvokeAll5() { + ExecutorService e = new ScheduledThreadPoolExecutor(2); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + l.add(new StringTask()); + List<Future<String>> result = e.invokeAll(l); + assertEquals(2, result.size()); + for (Iterator<Future<String>> it = result.iterator(); it.hasNext();) + assertSame(TEST_STRING, it.next().get()); + } catch (ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAny(null) throws NPE + */ + public void testTimedInvokeAny1() { + ExecutorService e = new ScheduledThreadPoolExecutor(2); + try { + e.invokeAny(null, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAny(,,null) throws NPE + */ + public void testTimedInvokeAnyNullTimeUnit() { + ExecutorService e = new ScheduledThreadPoolExecutor(2); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + e.invokeAny(l, MEDIUM_DELAY_MS, null); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAny(empty collection) throws IAE + */ + public void testTimedInvokeAny2() { + ExecutorService e = new ScheduledThreadPoolExecutor(2); + try { + e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + } catch (IllegalArgumentException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAny(c) throws NPE if c has null elements + */ + public void testTimedInvokeAny3() { + ExecutorService e = new ScheduledThreadPoolExecutor(2); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + l.add(null); + e.invokeAny(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + } catch (NullPointerException success) { + } catch(Exception ex) { + ex.printStackTrace(); + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAny(c) throws ExecutionException if no task completes + */ + public void testTimedInvokeAny4() { + ExecutorService e = new ScheduledThreadPoolExecutor(2); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new NPETask()); + e.invokeAny(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + } catch(ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAny(c) returns result of some task + */ + public void testTimedInvokeAny5() { + ExecutorService e = new ScheduledThreadPoolExecutor(2); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + l.add(new StringTask()); + String result = e.invokeAny(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + assertSame(TEST_STRING, result); + } catch (ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAll(null) throws NPE + */ + public void testTimedInvokeAll1() { + ExecutorService e = new ScheduledThreadPoolExecutor(2); + try { + e.invokeAll(null, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAll(,,null) throws NPE + */ + public void testTimedInvokeAllNullTimeUnit() { + ExecutorService e = new ScheduledThreadPoolExecutor(2); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + e.invokeAll(l, MEDIUM_DELAY_MS, null); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAll(empty collection) returns empty collection + */ + public void testTimedInvokeAll2() { + ExecutorService e = new ScheduledThreadPoolExecutor(2); + try { + List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + assertTrue(r.isEmpty()); + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAll(c) throws NPE if c has null elements + */ + public void testTimedInvokeAll3() { + ExecutorService e = new ScheduledThreadPoolExecutor(2); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + l.add(null); + e.invokeAll(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * get of element of invokeAll(c) throws exception on failed task + */ + public void testTimedInvokeAll4() { + ExecutorService e = new ScheduledThreadPoolExecutor(2); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new NPETask()); + List<Future<String>> result = e.invokeAll(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + assertEquals(1, result.size()); + for (Iterator<Future<String>> it = result.iterator(); it.hasNext();) + it.next().get(); + } catch(ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAll(c) returns results of all completed tasks + */ + public void testTimedInvokeAll5() { + ExecutorService e = new ScheduledThreadPoolExecutor(2); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + l.add(new StringTask()); + List<Future<String>> result = e.invokeAll(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + assertEquals(2, result.size()); + for (Iterator<Future<String>> it = result.iterator(); it.hasNext();) + assertSame(TEST_STRING, it.next().get()); + } catch (ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAll(c) cancels tasks not completed by timeout + */ + public void testTimedInvokeAll6() { + ExecutorService e = new ScheduledThreadPoolExecutor(2); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + l.add(Executors.callable(new MediumPossiblyInterruptedRunnable(), TEST_STRING)); + l.add(new StringTask()); + List<Future<String>> result = e.invokeAll(l, SHORT_DELAY_MS, TimeUnit.MILLISECONDS); + assertEquals(3, result.size()); + Iterator<Future<String>> it = result.iterator(); + Future<String> f1 = it.next(); + Future<String> f2 = it.next(); + Future<String> f3 = it.next(); + assertTrue(f1.isDone()); + assertTrue(f2.isDone()); + assertTrue(f3.isDone()); + assertFalse(f1.isCancelled()); + assertTrue(f2.isCancelled()); + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/SemaphoreTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/SemaphoreTest.java new file mode 100755 index 0000000..4019812 --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/SemaphoreTest.java @@ -0,0 +1,919 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.*; +import java.util.concurrent.*; +import java.io.*; + +public class SemaphoreTest extends JSR166TestCase { + public static void main(String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(SemaphoreTest.class); + } + + /** + * Subclass to expose protected methods + */ + static class PublicSemaphore extends Semaphore { + PublicSemaphore(int p, boolean f) { super(p, f); } + public Collection<Thread> getQueuedThreads() { + return super.getQueuedThreads(); + } + public void reducePermits(int p) { + super.reducePermits(p); + } + } + + /** + * A runnable calling acquire + */ + class InterruptibleLockRunnable implements Runnable { + final Semaphore lock; + InterruptibleLockRunnable(Semaphore l) { lock = l; } + public void run() { + try { + lock.acquire(); + } catch(InterruptedException success){} + } + } + + + /** + * A runnable calling acquire that expects to be + * interrupted + */ + class InterruptedLockRunnable implements Runnable { + final Semaphore lock; + InterruptedLockRunnable(Semaphore l) { lock = l; } + public void run() { + try { + lock.acquire(); + threadShouldThrow(); + } catch(InterruptedException success){} + } + } + + /** + * Zero, negative, and positive initial values are allowed in constructor + */ + public void testConstructor() { + Semaphore s0 = new Semaphore(0, false); + assertEquals(0, s0.availablePermits()); + assertFalse(s0.isFair()); + Semaphore s1 = new Semaphore(-1, false); + assertEquals(-1, s1.availablePermits()); + assertFalse(s1.isFair()); + Semaphore s2 = new Semaphore(-1, false); + assertEquals(-1, s2.availablePermits()); + assertFalse(s2.isFair()); + } + + /** + * Constructor without fairness argument behaves as nonfair + */ + public void testConstructor2() { + Semaphore s0 = new Semaphore(0); + assertEquals(0, s0.availablePermits()); + assertFalse(s0.isFair()); + Semaphore s1 = new Semaphore(-1); + assertEquals(-1, s1.availablePermits()); + assertFalse(s1.isFair()); + Semaphore s2 = new Semaphore(-1); + assertEquals(-1, s2.availablePermits()); + assertFalse(s2.isFair()); + } + + /** + * tryAcquire succeeds when sufficient permits, else fails + */ + public void testTryAcquireInSameThread() { + Semaphore s = new Semaphore(2, false); + assertEquals(2, s.availablePermits()); + assertTrue(s.tryAcquire()); + assertTrue(s.tryAcquire()); + assertEquals(0, s.availablePermits()); + assertFalse(s.tryAcquire()); + } + + /** + * Acquire and release of semaphore succeed if initially available + */ + public void testAcquireReleaseInSameThread() { + Semaphore s = new Semaphore(1, false); + try { + s.acquire(); + s.release(); + s.acquire(); + s.release(); + s.acquire(); + s.release(); + s.acquire(); + s.release(); + s.acquire(); + s.release(); + assertEquals(1, s.availablePermits()); + } catch( InterruptedException e){ + unexpectedException(); + } + } + + /** + * Uninterruptible acquire and release of semaphore succeed if + * initially available + */ + public void testAcquireUninterruptiblyReleaseInSameThread() { + Semaphore s = new Semaphore(1, false); + try { + s.acquireUninterruptibly(); + s.release(); + s.acquireUninterruptibly(); + s.release(); + s.acquireUninterruptibly(); + s.release(); + s.acquireUninterruptibly(); + s.release(); + s.acquireUninterruptibly(); + s.release(); + assertEquals(1, s.availablePermits()); + } finally { + } + } + + /** + * Timed Acquire and release of semaphore succeed if + * initially available + */ + public void testTimedAcquireReleaseInSameThread() { + Semaphore s = new Semaphore(1, false); + try { + assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + s.release(); + assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + s.release(); + assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + s.release(); + assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + s.release(); + assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + s.release(); + assertEquals(1, s.availablePermits()); + } catch( InterruptedException e){ + unexpectedException(); + } + } + + /** + * A release in one thread enables an acquire in another thread + */ + public void testAcquireReleaseInDifferentThreads() { + final Semaphore s = new Semaphore(0, false); + Thread t = new Thread(new Runnable() { + public void run() { + try { + s.acquire(); + s.release(); + s.release(); + s.acquire(); + } catch(InterruptedException ie){ + threadUnexpectedException(); + } + } + }); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + s.release(); + s.release(); + s.acquire(); + s.acquire(); + s.release(); + t.join(); + } catch( InterruptedException e){ + unexpectedException(); + } + } + + /** + * A release in one thread enables an uninterruptible acquire in another thread + */ + public void testUninterruptibleAcquireReleaseInDifferentThreads() { + final Semaphore s = new Semaphore(0, false); + Thread t = new Thread(new Runnable() { + public void run() { + s.acquireUninterruptibly(); + s.release(); + s.release(); + s.acquireUninterruptibly(); + } + }); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + s.release(); + s.release(); + s.acquireUninterruptibly(); + s.acquireUninterruptibly(); + s.release(); + t.join(); + } catch( InterruptedException e){ + unexpectedException(); + } + } + + + /** + * A release in one thread enables a timed acquire in another thread + */ + public void testTimedAcquireReleaseInDifferentThreads() { + final Semaphore s = new Semaphore(1, false); + Thread t = new Thread(new Runnable() { + public void run() { + try { + s.release(); + threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + s.release(); + threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + + } catch(InterruptedException ie){ + threadUnexpectedException(); + } + } + }); + try { + t.start(); + assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + s.release(); + assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + s.release(); + s.release(); + t.join(); + } catch( InterruptedException e){ + unexpectedException(); + } + } + + /** + * A waiting acquire blocks interruptibly + */ + public void testAcquire_InterruptedException() { + final Semaphore s = new Semaphore(0, false); + Thread t = new Thread(new Runnable() { + public void run() { + try { + s.acquire(); + threadShouldThrow(); + } catch(InterruptedException success){} + } + }); + t.start(); + try { + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } catch(InterruptedException e){ + unexpectedException(); + } + } + + /** + * A waiting timed acquire blocks interruptibly + */ + public void testTryAcquire_InterruptedException() { + final Semaphore s = new Semaphore(0, false); + Thread t = new Thread(new Runnable() { + public void run() { + try { + s.tryAcquire(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + threadShouldThrow(); + } catch(InterruptedException success){ + } + } + }); + t.start(); + try { + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } catch(InterruptedException e){ + unexpectedException(); + } + } + + /** + * hasQueuedThreads reports whether there are waiting threads + */ + public void testHasQueuedThreads() { + final Semaphore lock = new Semaphore(1, false); + Thread t1 = new Thread(new InterruptedLockRunnable(lock)); + Thread t2 = new Thread(new InterruptibleLockRunnable(lock)); + try { + assertFalse(lock.hasQueuedThreads()); + lock.acquireUninterruptibly(); + t1.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(lock.hasQueuedThreads()); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(lock.hasQueuedThreads()); + t1.interrupt(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(lock.hasQueuedThreads()); + lock.release(); + Thread.sleep(SHORT_DELAY_MS); + assertFalse(lock.hasQueuedThreads()); + t1.join(); + t2.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * getQueueLength reports number of waiting threads + */ + public void testGetQueueLength() { + final Semaphore lock = new Semaphore(1, false); + Thread t1 = new Thread(new InterruptedLockRunnable(lock)); + Thread t2 = new Thread(new InterruptibleLockRunnable(lock)); + try { + assertEquals(0, lock.getQueueLength()); + lock.acquireUninterruptibly(); + t1.start(); + Thread.sleep(SHORT_DELAY_MS); + assertEquals(1, lock.getQueueLength()); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + assertEquals(2, lock.getQueueLength()); + t1.interrupt(); + Thread.sleep(SHORT_DELAY_MS); + assertEquals(1, lock.getQueueLength()); + lock.release(); + Thread.sleep(SHORT_DELAY_MS); + assertEquals(0, lock.getQueueLength()); + t1.join(); + t2.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * getQueuedThreads includes waiting threads + */ + public void testGetQueuedThreads() { + final PublicSemaphore lock = new PublicSemaphore(1, false); + Thread t1 = new Thread(new InterruptedLockRunnable(lock)); + Thread t2 = new Thread(new InterruptibleLockRunnable(lock)); + try { + assertTrue(lock.getQueuedThreads().isEmpty()); + lock.acquireUninterruptibly(); + assertTrue(lock.getQueuedThreads().isEmpty()); + t1.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(lock.getQueuedThreads().contains(t1)); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(lock.getQueuedThreads().contains(t1)); + assertTrue(lock.getQueuedThreads().contains(t2)); + t1.interrupt(); + Thread.sleep(SHORT_DELAY_MS); + assertFalse(lock.getQueuedThreads().contains(t1)); + assertTrue(lock.getQueuedThreads().contains(t2)); + lock.release(); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(lock.getQueuedThreads().isEmpty()); + t1.join(); + t2.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * drainPermits reports and removes given number of permits + */ + public void testDrainPermits() { + Semaphore s = new Semaphore(0, false); + assertEquals(0, s.availablePermits()); + assertEquals(0, s.drainPermits()); + s.release(10); + assertEquals(10, s.availablePermits()); + assertEquals(10, s.drainPermits()); + assertEquals(0, s.availablePermits()); + assertEquals(0, s.drainPermits()); + } + + /** + * reducePermits reduces number of permits + */ + public void testReducePermits() { + PublicSemaphore s = new PublicSemaphore(10, false); + assertEquals(10, s.availablePermits()); + s.reducePermits(1); + assertEquals(9, s.availablePermits()); + s.reducePermits(10); + assertEquals(-1, s.availablePermits()); + } + + /** + * a deserialized serialized semaphore has same number of permits + */ + public void testSerialization() { + Semaphore l = new Semaphore(3, false); + try { + l.acquire(); + l.release(); + ByteArrayOutputStream bout = new ByteArrayOutputStream(10000); + ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout)); + out.writeObject(l); + out.close(); + + ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); + ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin)); + Semaphore r = (Semaphore) in.readObject(); + assertEquals(3, r.availablePermits()); + assertFalse(r.isFair()); + r.acquire(); + r.release(); + } catch(Exception e){ + unexpectedException(); + } + } + + + /** + * Zero, negative, and positive initial values are allowed in constructor + */ + public void testConstructor_fair() { + Semaphore s0 = new Semaphore(0, true); + assertEquals(0, s0.availablePermits()); + assertTrue(s0.isFair()); + Semaphore s1 = new Semaphore(-1, true); + assertEquals(-1, s1.availablePermits()); + Semaphore s2 = new Semaphore(-1, true); + assertEquals(-1, s2.availablePermits()); + } + + /** + * tryAcquire succeeds when sufficient permits, else fails + */ + public void testTryAcquireInSameThread_fair() { + Semaphore s = new Semaphore(2, true); + assertEquals(2, s.availablePermits()); + assertTrue(s.tryAcquire()); + assertTrue(s.tryAcquire()); + assertEquals(0, s.availablePermits()); + assertFalse(s.tryAcquire()); + } + + /** + * tryAcquire(n) succeeds when sufficient permits, else fails + */ + public void testTryAcquireNInSameThread_fair() { + Semaphore s = new Semaphore(2, true); + assertEquals(2, s.availablePermits()); + assertTrue(s.tryAcquire(2)); + assertEquals(0, s.availablePermits()); + assertFalse(s.tryAcquire()); + } + + /** + * Acquire and release of semaphore succeed if initially available + */ + public void testAcquireReleaseInSameThread_fair() { + Semaphore s = new Semaphore(1, true); + try { + s.acquire(); + s.release(); + s.acquire(); + s.release(); + s.acquire(); + s.release(); + s.acquire(); + s.release(); + s.acquire(); + s.release(); + assertEquals(1, s.availablePermits()); + } catch( InterruptedException e){ + unexpectedException(); + } + } + + /** + * Acquire(n) and release(n) of semaphore succeed if initially available + */ + public void testAcquireReleaseNInSameThread_fair() { + Semaphore s = new Semaphore(1, true); + try { + s.release(1); + s.acquire(1); + s.release(2); + s.acquire(2); + s.release(3); + s.acquire(3); + s.release(4); + s.acquire(4); + s.release(5); + s.acquire(5); + assertEquals(1, s.availablePermits()); + } catch( InterruptedException e){ + unexpectedException(); + } + } + + /** + * Acquire(n) and release(n) of semaphore succeed if initially available + */ + public void testAcquireUninterruptiblyReleaseNInSameThread_fair() { + Semaphore s = new Semaphore(1, true); + try { + s.release(1); + s.acquireUninterruptibly(1); + s.release(2); + s.acquireUninterruptibly(2); + s.release(3); + s.acquireUninterruptibly(3); + s.release(4); + s.acquireUninterruptibly(4); + s.release(5); + s.acquireUninterruptibly(5); + assertEquals(1, s.availablePermits()); + } finally { + } + } + + /** + * release(n) in one thread enables timed acquire(n) in another thread + */ + public void testTimedAcquireReleaseNInSameThread_fair() { + Semaphore s = new Semaphore(1, true); + try { + s.release(1); + assertTrue(s.tryAcquire(1, SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + s.release(2); + assertTrue(s.tryAcquire(2, SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + s.release(3); + assertTrue(s.tryAcquire(3, SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + s.release(4); + assertTrue(s.tryAcquire(4, SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + s.release(5); + assertTrue(s.tryAcquire(5, SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + assertEquals(1, s.availablePermits()); + } catch( InterruptedException e){ + unexpectedException(); + } + } + + /** + * release in one thread enables timed acquire in another thread + */ + public void testTimedAcquireReleaseInSameThread_fair() { + Semaphore s = new Semaphore(1, true); + try { + assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + s.release(); + assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + s.release(); + assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + s.release(); + assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + s.release(); + assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + s.release(); + assertEquals(1, s.availablePermits()); + } catch( InterruptedException e){ + unexpectedException(); + } + } + + /** + * A release in one thread enables an acquire in another thread + */ + public void testAcquireReleaseInDifferentThreads_fair() { + final Semaphore s = new Semaphore(0, true); + Thread t = new Thread(new Runnable() { + public void run() { + try { + s.acquire(); + s.acquire(); + s.acquire(); + s.acquire(); + } catch(InterruptedException ie){ + threadUnexpectedException(); + } + } + }); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + s.release(); + s.release(); + s.release(); + s.release(); + s.release(); + s.release(); + t.join(); + assertEquals(2, s.availablePermits()); + } catch( InterruptedException e){ + unexpectedException(); + } + } + + /** + * release(n) in one thread enables acquire(n) in another thread + */ + public void testAcquireReleaseNInDifferentThreads_fair() { + final Semaphore s = new Semaphore(0, true); + Thread t = new Thread(new Runnable() { + public void run() { + try { + s.acquire(); + s.release(2); + s.acquire(); + } catch(InterruptedException ie){ + threadUnexpectedException(); + } + } + }); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + s.release(2); + s.acquire(2); + s.release(1); + t.join(); + } catch( InterruptedException e){ + unexpectedException(); + } + } + + /** + * release(n) in one thread enables acquire(n) in another thread + */ + public void testAcquireReleaseNInDifferentThreads_fair2() { + final Semaphore s = new Semaphore(0, true); + Thread t = new Thread(new Runnable() { + public void run() { + try { + s.acquire(2); + s.acquire(2); + s.release(4); + } catch(InterruptedException ie){ + threadUnexpectedException(); + } + } + }); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + s.release(6); + s.acquire(2); + s.acquire(2); + s.release(2); + t.join(); + } catch( InterruptedException e){ + unexpectedException(); + } + } + + + + + + /** + * release in one thread enables timed acquire in another thread + */ + public void testTimedAcquireReleaseInDifferentThreads_fair() { + final Semaphore s = new Semaphore(1, true); + Thread t = new Thread(new Runnable() { + public void run() { + try { + threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + + } catch(InterruptedException ie){ + threadUnexpectedException(); + } + } + }); + t.start(); + try { + s.release(); + s.release(); + s.release(); + s.release(); + s.release(); + t.join(); + } catch( InterruptedException e){ + unexpectedException(); + } + } + + /** + * release(n) in one thread enables timed acquire(n) in another thread + */ + public void testTimedAcquireReleaseNInDifferentThreads_fair() { + final Semaphore s = new Semaphore(2, true); + Thread t = new Thread(new Runnable() { + public void run() { + try { + threadAssertTrue(s.tryAcquire(2, SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + s.release(2); + threadAssertTrue(s.tryAcquire(2, SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + s.release(2); + } catch(InterruptedException ie){ + threadUnexpectedException(); + } + } + }); + t.start(); + try { + assertTrue(s.tryAcquire(2, SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + s.release(2); + assertTrue(s.tryAcquire(2, SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + s.release(2); + t.join(); + } catch( InterruptedException e){ + unexpectedException(); + } + } + + /** + * A waiting acquire blocks interruptibly + */ + public void testAcquire_InterruptedException_fair() { + final Semaphore s = new Semaphore(0, true); + Thread t = new Thread(new Runnable() { + public void run() { + try { + s.acquire(); + threadShouldThrow(); + } catch(InterruptedException success){} + } + }); + t.start(); + try { + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } catch(InterruptedException e){ + unexpectedException(); + } + } + + /** + * A waiting acquire(n) blocks interruptibly + */ + public void testAcquireN_InterruptedException_fair() { + final Semaphore s = new Semaphore(2, true); + Thread t = new Thread(new Runnable() { + public void run() { + try { + s.acquire(3); + threadShouldThrow(); + } catch(InterruptedException success){} + } + }); + t.start(); + try { + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } catch(InterruptedException e){ + unexpectedException(); + } + } + + /** + * A waiting tryAcquire blocks interruptibly + */ + public void testTryAcquire_InterruptedException_fair() { + final Semaphore s = new Semaphore(0, true); + Thread t = new Thread(new Runnable() { + public void run() { + try { + s.tryAcquire(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + threadShouldThrow(); + } catch(InterruptedException success){ + } + } + }); + t.start(); + try { + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } catch(InterruptedException e){ + unexpectedException(); + } + } + + /** + * A waiting tryAcquire(n) blocks interruptibly + */ + public void testTryAcquireN_InterruptedException_fair() { + final Semaphore s = new Semaphore(1, true); + Thread t = new Thread(new Runnable() { + public void run() { + try { + s.tryAcquire(4, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + threadShouldThrow(); + } catch(InterruptedException success){ + } + } + }); + t.start(); + try { + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } catch(InterruptedException e){ + unexpectedException(); + } + } + + /** + * getQueueLength reports number of waiting threads + */ + public void testGetQueueLength_fair() { + final Semaphore lock = new Semaphore(1, true); + Thread t1 = new Thread(new InterruptedLockRunnable(lock)); + Thread t2 = new Thread(new InterruptibleLockRunnable(lock)); + try { + assertEquals(0, lock.getQueueLength()); + lock.acquireUninterruptibly(); + t1.start(); + Thread.sleep(SHORT_DELAY_MS); + assertEquals(1, lock.getQueueLength()); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + assertEquals(2, lock.getQueueLength()); + t1.interrupt(); + Thread.sleep(SHORT_DELAY_MS); + assertEquals(1, lock.getQueueLength()); + lock.release(); + Thread.sleep(SHORT_DELAY_MS); + assertEquals(0, lock.getQueueLength()); + t1.join(); + t2.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + + /** + * a deserialized serialized semaphore has same number of permits + */ + public void testSerialization_fair() { + Semaphore l = new Semaphore(3, true); + + try { + l.acquire(); + l.release(); + ByteArrayOutputStream bout = new ByteArrayOutputStream(10000); + ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout)); + out.writeObject(l); + out.close(); + + ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); + ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin)); + Semaphore r = (Semaphore) in.readObject(); + assertEquals(3, r.availablePermits()); + assertTrue(r.isFair()); + r.acquire(); + r.release(); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * toString indicates current number of permits + */ + public void testToString() { + Semaphore s = new Semaphore(0); + String us = s.toString(); + assertTrue(us.indexOf("Permits = 0") >= 0); + s.release(); + String s1 = s.toString(); + assertTrue(s1.indexOf("Permits = 1") >= 0); + s.release(); + String s2 = s.toString(); + assertTrue(s2.indexOf("Permits = 2") >= 0); + } + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/SynchronousQueueTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/SynchronousQueueTest.java new file mode 100755 index 0000000..19bdede --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/SynchronousQueueTest.java @@ -0,0 +1,895 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.*; +import java.util.concurrent.*; +import java.io.*; + +public class SynchronousQueueTest extends JSR166TestCase { + + public static void main(String[] args) { + junit.textui.TestRunner.run (suite()); + } + + public static Test suite() { + return new TestSuite(SynchronousQueueTest.class); + } + + /** + * A SynchronousQueue is both empty and full + */ + public void testEmptyFull() { + SynchronousQueue q = new SynchronousQueue(); + assertTrue(q.isEmpty()); + assertEquals(0, q.size()); + assertEquals(0, q.remainingCapacity()); + assertFalse(q.offer(zero)); + } + + /** + * A fair SynchronousQueue is both empty and full + */ + public void testFairEmptyFull() { + SynchronousQueue q = new SynchronousQueue(true); + assertTrue(q.isEmpty()); + assertEquals(0, q.size()); + assertEquals(0, q.remainingCapacity()); + assertFalse(q.offer(zero)); + } + + /** + * offer(null) throws NPE + */ + public void testOfferNull() { + try { + SynchronousQueue q = new SynchronousQueue(); + q.offer(null); + shouldThrow(); + } catch (NullPointerException success) { } + } + + /** + * add(null) throws NPE + */ + public void testAddNull() { + try { + SynchronousQueue q = new SynchronousQueue(); + q.add(null); + shouldThrow(); + } catch (NullPointerException success) { } + } + + /** + * offer fails if no active taker + */ + public void testOffer() { + SynchronousQueue q = new SynchronousQueue(); + assertFalse(q.offer(one)); + } + + /** + * add throws ISE if no active taker + */ + public void testAdd() { + try { + SynchronousQueue q = new SynchronousQueue(); + assertEquals(0, q.remainingCapacity()); + q.add(one); + shouldThrow(); + } catch (IllegalStateException success){ + } + } + + /** + * addAll(null) throws NPE + */ + public void testAddAll1() { + try { + SynchronousQueue q = new SynchronousQueue(); + q.addAll(null); + shouldThrow(); + } + catch (NullPointerException success) {} + } + + /** + * addAll(this) throws IAE + */ + public void testAddAllSelf() { + try { + SynchronousQueue q = new SynchronousQueue(); + q.addAll(q); + shouldThrow(); + } + catch (IllegalArgumentException success) {} + } + + /** + * addAll of a collection with null elements throws NPE + */ + public void testAddAll2() { + try { + SynchronousQueue q = new SynchronousQueue(); + Integer[] ints = new Integer[1]; + q.addAll(Arrays.asList(ints)); + shouldThrow(); + } + catch (NullPointerException success) {} + } + /** + * addAll throws ISE if no active taker + */ + public void testAddAll4() { + try { + SynchronousQueue q = new SynchronousQueue(); + Integer[] ints = new Integer[1]; + for (int i = 0; i < 1; ++i) + ints[i] = new Integer(i); + q.addAll(Arrays.asList(ints)); + shouldThrow(); + } + catch (IllegalStateException success) {} + } + + /** + * put(null) throws NPE + */ + public void testPutNull() { + try { + SynchronousQueue q = new SynchronousQueue(); + q.put(null); + shouldThrow(); + } + catch (NullPointerException success){ + } + catch (InterruptedException ie) { + unexpectedException(); + } + } + + /** + * put blocks interruptibly if no active taker + */ + public void testBlockingPut() { + Thread t = new Thread(new Runnable() { + public void run() { + try { + SynchronousQueue q = new SynchronousQueue(); + q.put(zero); + threadShouldThrow(); + } catch (InterruptedException ie){ + } + }}); + t.start(); + try { + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } + catch (InterruptedException ie) { + unexpectedException(); + } + } + + /** + * put blocks waiting for take + */ + public void testPutWithTake() { + final SynchronousQueue q = new SynchronousQueue(); + Thread t = new Thread(new Runnable() { + public void run() { + int added = 0; + try { + q.put(new Object()); + ++added; + q.put(new Object()); + ++added; + q.put(new Object()); + ++added; + q.put(new Object()); + ++added; + threadShouldThrow(); + } catch (InterruptedException e){ + assertTrue(added >= 1); + } + } + }); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + q.take(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } catch (Exception e){ + unexpectedException(); + } + } + + /** + * timed offer times out if elements not taken + */ + public void testTimedOffer() { + final SynchronousQueue q = new SynchronousQueue(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + + threadAssertFalse(q.offer(new Object(), SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + q.offer(new Object(), LONG_DELAY_MS, TimeUnit.MILLISECONDS); + threadShouldThrow(); + } catch (InterruptedException success){} + } + }); + + try { + t.start(); + Thread.sleep(SMALL_DELAY_MS); + t.interrupt(); + t.join(); + } catch (Exception e){ + unexpectedException(); + } + } + + + /** + * take blocks interruptibly when empty + */ + public void testTakeFromEmpty() { + final SynchronousQueue q = new SynchronousQueue(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + q.take(); + threadShouldThrow(); + } catch (InterruptedException success){ } + } + }); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } catch (Exception e){ + unexpectedException(); + } + } + + + /** + * put blocks interruptibly if no active taker + */ + public void testFairBlockingPut() { + Thread t = new Thread(new Runnable() { + public void run() { + try { + SynchronousQueue q = new SynchronousQueue(true); + q.put(zero); + threadShouldThrow(); + } catch (InterruptedException ie){ + } + }}); + t.start(); + try { + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } + catch (InterruptedException ie) { + unexpectedException(); + } + } + + /** + * put blocks waiting for take + */ + public void testFairPutWithTake() { + final SynchronousQueue q = new SynchronousQueue(true); + Thread t = new Thread(new Runnable() { + public void run() { + int added = 0; + try { + q.put(new Object()); + ++added; + q.put(new Object()); + ++added; + q.put(new Object()); + ++added; + q.put(new Object()); + ++added; + threadShouldThrow(); + } catch (InterruptedException e){ + assertTrue(added >= 1); + } + } + }); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + q.take(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } catch (Exception e){ + unexpectedException(); + } + } + + /** + * timed offer times out if elements not taken + */ + public void testFairTimedOffer() { + final SynchronousQueue q = new SynchronousQueue(true); + Thread t = new Thread(new Runnable() { + public void run() { + try { + + threadAssertFalse(q.offer(new Object(), SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + q.offer(new Object(), LONG_DELAY_MS, TimeUnit.MILLISECONDS); + threadShouldThrow(); + } catch (InterruptedException success){} + } + }); + + try { + t.start(); + Thread.sleep(SMALL_DELAY_MS); + t.interrupt(); + t.join(); + } catch (Exception e){ + unexpectedException(); + } + } + + + /** + * take blocks interruptibly when empty + */ + public void testFairTakeFromEmpty() { + final SynchronousQueue q = new SynchronousQueue(true); + Thread t = new Thread(new Runnable() { + public void run() { + try { + q.take(); + threadShouldThrow(); + } catch (InterruptedException success){ } + } + }); + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } catch (Exception e){ + unexpectedException(); + } + } + + /** + * poll fails unless active taker + */ + public void testPoll() { + SynchronousQueue q = new SynchronousQueue(); + assertNull(q.poll()); + } + + /** + * timed pool with zero timeout times out if no active taker + */ + public void testTimedPoll0() { + try { + SynchronousQueue q = new SynchronousQueue(); + assertNull(q.poll(0, TimeUnit.MILLISECONDS)); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * timed pool with nonzero timeout times out if no active taker + */ + public void testTimedPoll() { + try { + SynchronousQueue q = new SynchronousQueue(); + assertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + } catch (InterruptedException e){ + unexpectedException(); + } + } + + /** + * Interrupted timed poll throws InterruptedException instead of + * returning timeout status + */ + public void testInterruptedTimedPoll() { + Thread t = new Thread(new Runnable() { + public void run() { + try { + SynchronousQueue q = new SynchronousQueue(); + assertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + } catch (InterruptedException success){ + } + }}); + t.start(); + try { + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } + catch (InterruptedException ie) { + unexpectedException(); + } + } + + /** + * timed poll before a delayed offer fails; after offer succeeds; + * on interruption throws + */ + public void testTimedPollWithOffer() { + final SynchronousQueue q = new SynchronousQueue(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS); + q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS); + threadShouldThrow(); + } catch (InterruptedException success) { } + } + }); + try { + t.start(); + Thread.sleep(SMALL_DELAY_MS); + assertTrue(q.offer(zero, SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + t.interrupt(); + t.join(); + } catch (Exception e){ + unexpectedException(); + } + } + + /** + * Interrupted timed poll throws InterruptedException instead of + * returning timeout status + */ + public void testFairInterruptedTimedPoll() { + Thread t = new Thread(new Runnable() { + public void run() { + try { + SynchronousQueue q = new SynchronousQueue(true); + assertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + } catch (InterruptedException success){ + } + }}); + t.start(); + try { + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } + catch (InterruptedException ie) { + unexpectedException(); + } + } + + /** + * timed poll before a delayed offer fails; after offer succeeds; + * on interruption throws + */ + public void testFairTimedPollWithOffer() { + final SynchronousQueue q = new SynchronousQueue(true); + Thread t = new Thread(new Runnable() { + public void run() { + try { + threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS); + q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS); + threadShouldThrow(); + } catch (InterruptedException success) { } + } + }); + try { + t.start(); + Thread.sleep(SMALL_DELAY_MS); + assertTrue(q.offer(zero, SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + t.interrupt(); + t.join(); + } catch (Exception e){ + unexpectedException(); + } + } + + + /** + * peek returns null + */ + public void testPeek() { + SynchronousQueue q = new SynchronousQueue(); + assertNull(q.peek()); + } + + /** + * element throws NSEE + */ + public void testElement() { + SynchronousQueue q = new SynchronousQueue(); + try { + q.element(); + shouldThrow(); + } + catch (NoSuchElementException success) {} + } + + /** + * remove throws NSEE if no active taker + */ + public void testRemove() { + SynchronousQueue q = new SynchronousQueue(); + try { + q.remove(); + shouldThrow(); + } catch (NoSuchElementException success){ + } + } + + /** + * remove(x) returns false + */ + public void testRemoveElement() { + SynchronousQueue q = new SynchronousQueue(); + assertFalse(q.remove(zero)); + assertTrue(q.isEmpty()); + } + + /** + * contains returns false + */ + public void testContains() { + SynchronousQueue q = new SynchronousQueue(); + assertFalse(q.contains(zero)); + } + + /** + * clear ensures isEmpty + */ + public void testClear() { + SynchronousQueue q = new SynchronousQueue(); + q.clear(); + assertTrue(q.isEmpty()); + } + + /** + * containsAll returns false unless empty + */ + public void testContainsAll() { + SynchronousQueue q = new SynchronousQueue(); + Integer[] empty = new Integer[0]; + assertTrue(q.containsAll(Arrays.asList(empty))); + Integer[] ints = new Integer[1]; ints[0] = zero; + assertFalse(q.containsAll(Arrays.asList(ints))); + } + + /** + * retainAll returns false + */ + public void testRetainAll() { + SynchronousQueue q = new SynchronousQueue(); + Integer[] empty = new Integer[0]; + assertFalse(q.retainAll(Arrays.asList(empty))); + Integer[] ints = new Integer[1]; ints[0] = zero; + assertFalse(q.retainAll(Arrays.asList(ints))); + } + + /** + * removeAll returns false + */ + public void testRemoveAll() { + SynchronousQueue q = new SynchronousQueue(); + Integer[] empty = new Integer[0]; + assertFalse(q.removeAll(Arrays.asList(empty))); + Integer[] ints = new Integer[1]; ints[0] = zero; + assertFalse(q.containsAll(Arrays.asList(ints))); + } + + + /** + * toArray is empty + */ + public void testToArray() { + SynchronousQueue q = new SynchronousQueue(); + Object[] o = q.toArray(); + assertEquals(o.length, 0); + } + + /** + * toArray(a) is nulled at position 0 + */ + public void testToArray2() { + SynchronousQueue q = new SynchronousQueue(); + Integer[] ints = new Integer[1]; + assertNull(ints[0]); + } + + /** + * toArray(null) throws NPE + */ + public void testToArray_BadArg() { + try { + SynchronousQueue q = new SynchronousQueue(); + Object o[] = q.toArray(null); + shouldThrow(); + } catch(NullPointerException success){} + } + + + /** + * iterator does not traverse any elements + */ + public void testIterator() { + SynchronousQueue q = new SynchronousQueue(); + Iterator it = q.iterator(); + assertFalse(it.hasNext()); + try { + Object x = it.next(); + shouldThrow(); + } + catch (NoSuchElementException success) {} + } + + /** + * iterator remove throws ISE + */ + public void testIteratorRemove() { + SynchronousQueue q = new SynchronousQueue(); + Iterator it = q.iterator(); + try { + it.remove(); + shouldThrow(); + } + catch (IllegalStateException success) {} + } + + /** + * toString returns a non-null string + */ + public void testToString() { + SynchronousQueue q = new SynchronousQueue(); + String s = q.toString(); + assertNotNull(s); + } + + + /** + * offer transfers elements across Executor tasks + */ + public void testOfferInExecutor() { + final SynchronousQueue q = new SynchronousQueue(); + ExecutorService executor = Executors.newFixedThreadPool(2); + final Integer one = new Integer(1); + + executor.execute(new Runnable() { + public void run() { + threadAssertFalse(q.offer(one)); + try { + threadAssertTrue(q.offer(one, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS)); + threadAssertEquals(0, q.remainingCapacity()); + } + catch (InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + executor.execute(new Runnable() { + public void run() { + try { + Thread.sleep(SMALL_DELAY_MS); + threadAssertEquals(one, q.take()); + } + catch (InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + joinPool(executor); + + } + + /** + * poll retrieves elements across Executor threads + */ + public void testPollInExecutor() { + final SynchronousQueue q = new SynchronousQueue(); + ExecutorService executor = Executors.newFixedThreadPool(2); + executor.execute(new Runnable() { + public void run() { + threadAssertNull(q.poll()); + try { + threadAssertTrue(null != q.poll(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS)); + threadAssertTrue(q.isEmpty()); + } + catch (InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + executor.execute(new Runnable() { + public void run() { + try { + Thread.sleep(SMALL_DELAY_MS); + q.put(new Integer(1)); + } + catch (InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + joinPool(executor); + } + + /** + * a deserialized serialized queue is usable + */ + public void testSerialization() { + SynchronousQueue q = new SynchronousQueue(); + try { + ByteArrayOutputStream bout = new ByteArrayOutputStream(10000); + ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout)); + out.writeObject(q); + out.close(); + + ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); + ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin)); + SynchronousQueue r = (SynchronousQueue)in.readObject(); + assertEquals(q.size(), r.size()); + while (!q.isEmpty()) + assertEquals(q.remove(), r.remove()); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * drainTo(null) throws NPE + */ + public void testDrainToNull() { + SynchronousQueue q = new SynchronousQueue(); + try { + q.drainTo(null); + shouldThrow(); + } catch(NullPointerException success) { + } + } + + /** + * drainTo(this) throws IAE + */ + public void testDrainToSelf() { + SynchronousQueue q = new SynchronousQueue(); + try { + q.drainTo(q); + shouldThrow(); + } catch(IllegalArgumentException success) { + } + } + + /** + * drainTo(c) of empty queue doesn't transfer elements + */ + public void testDrainTo() { + SynchronousQueue q = new SynchronousQueue(); + ArrayList l = new ArrayList(); + q.drainTo(l); + assertEquals(q.size(), 0); + assertEquals(l.size(), 0); + } + + /** + * drainTo empties queue, unblocking a waiting put. + */ + public void testDrainToWithActivePut() { + final SynchronousQueue q = new SynchronousQueue(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + q.put(new Integer(1)); + } catch (InterruptedException ie){ + threadUnexpectedException(); + } + } + }); + try { + t.start(); + ArrayList l = new ArrayList(); + Thread.sleep(SHORT_DELAY_MS); + q.drainTo(l); + assertTrue(l.size() <= 1); + if (l.size() > 0) + assertEquals(l.get(0), new Integer(1)); + t.join(); + assertTrue(l.size() <= 1); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * drainTo(null, n) throws NPE + */ + public void testDrainToNullN() { + SynchronousQueue q = new SynchronousQueue(); + try { + q.drainTo(null, 0); + shouldThrow(); + } catch(NullPointerException success) { + } + } + + /** + * drainTo(this, n) throws IAE + */ + public void testDrainToSelfN() { + SynchronousQueue q = new SynchronousQueue(); + try { + q.drainTo(q, 0); + shouldThrow(); + } catch(IllegalArgumentException success) { + } + } + + /** + * drainTo(c, n) empties up to n elements of queue into c + */ + public void testDrainToN() { + final SynchronousQueue q = new SynchronousQueue(); + Thread t1 = new Thread(new Runnable() { + public void run() { + try { + q.put(one); + } catch (InterruptedException ie){ + threadUnexpectedException(); + } + } + }); + Thread t2 = new Thread(new Runnable() { + public void run() { + try { + q.put(two); + } catch (InterruptedException ie){ + threadUnexpectedException(); + } + } + }); + + try { + t1.start(); + t2.start(); + ArrayList l = new ArrayList(); + Thread.sleep(SHORT_DELAY_MS); + q.drainTo(l, 1); + assertTrue(l.size() == 1); + q.drainTo(l, 1); + assertTrue(l.size() == 2); + assertTrue(l.contains(one)); + assertTrue(l.contains(two)); + t1.join(); + t2.join(); + } catch(Exception e){ + unexpectedException(); + } + } + + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/SystemTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/SystemTest.java new file mode 100644 index 0000000..4433cb1 --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/SystemTest.java @@ -0,0 +1,81 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; + +public class SystemTest extends JSR166TestCase { + public static void main(String[] args) { + junit.textui.TestRunner.run(suite()); + } + + public static Test suite() { + return new TestSuite(SystemTest.class); + } + + /** + * Worst case rounding for millisecs; set for 60 cycle millis clock. + * This value might need to be changed os JVMs with coarser + * System.currentTimeMillis clocks. + */ + static final long MILLIS_ROUND = 17; + + /** + * Nanos between readings of millis is no longer than millis (plus + * possible rounding). + * This shows only that nano timing not (much) worse than milli. + */ + public void testNanoTime1() { + try { + long m1 = System.currentTimeMillis(); + Thread.sleep(1); + long n1 = System.nanoTime(); + Thread.sleep(SHORT_DELAY_MS); + long n2 = System.nanoTime(); + Thread.sleep(1); + long m2 = System.currentTimeMillis(); + long millis = m2 - m1; + long nanos = n2 - n1; + assertTrue(nanos >= 0); + long nanosAsMillis = nanos / 1000000; + assertTrue(nanosAsMillis <= millis + MILLIS_ROUND); + } + catch(InterruptedException ie) { + unexpectedException(); + } + } + + /** + * Millis between readings of nanos is less than nanos, adjusting + * for rounding. + * This shows only that nano timing not (much) worse than milli. + */ + public void testNanoTime2() { + try { + long n1 = System.nanoTime(); + Thread.sleep(1); + long m1 = System.currentTimeMillis(); + Thread.sleep(SHORT_DELAY_MS); + long m2 = System.currentTimeMillis(); + Thread.sleep(1); + long n2 = System.nanoTime(); + long millis = m2 - m1; + long nanos = n2 - n1; + + assertTrue(nanos >= 0); + long nanosAsMillis = nanos / 1000000; + assertTrue(millis <= nanosAsMillis + MILLIS_ROUND); + } + catch(InterruptedException ie) { + unexpectedException(); + } + } + +} + diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadLocalTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadLocalTest.java new file mode 100644 index 0000000..0c2256a --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadLocalTest.java @@ -0,0 +1,108 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.concurrent.Semaphore; + +public class ThreadLocalTest extends JSR166TestCase { + public static void main(String[] args) { + junit.textui.TestRunner.run(suite()); + } + + public static Test suite() { + return new TestSuite(ThreadLocalTest.class); + } + + static ThreadLocal<Integer> tl = new ThreadLocal<Integer>() { + public Integer initialValue() { + return one; + } + }; + + static InheritableThreadLocal<Integer> itl = + new InheritableThreadLocal<Integer>() { + protected Integer initialValue() { + return zero; + } + + protected Integer childValue(Integer parentValue) { + return new Integer(parentValue.intValue() + 1); + } + }; + + /** + * remove causes next access to return initial value + */ + public void testRemove() { + assertEquals(tl.get(), one); + tl.set(two); + assertEquals(tl.get(), two); + tl.remove(); + assertEquals(tl.get(), one); + } + + /** + * remove in InheritableThreadLocal causes next access to return + * initial value + */ + public void testRemoveITL() { + assertEquals(itl.get(), zero); + itl.set(two); + assertEquals(itl.get(), two); + itl.remove(); + assertEquals(itl.get(), zero); + } + + private class ITLThread extends Thread { + final int[] x; + ITLThread(int[] array) { x = array; } + public void run() { + Thread child = null; + if (itl.get().intValue() < x.length - 1) { + child = new ITLThread(x); + child.start(); + } + Thread.currentThread().yield(); + + int threadId = itl.get().intValue(); + for (int j = 0; j < threadId; j++) { + x[threadId]++; + Thread.currentThread().yield(); + } + + if (child != null) { // Wait for child (if any) + try { + child.join(); + } catch(InterruptedException e) { + threadUnexpectedException(); + } + } + } + } + + /** + * InheritableThreadLocal propagates generic values. + */ + public void testGenericITL() { + final int threadCount = 10; + final int x[] = new int[threadCount]; + Thread progenitor = new ITLThread(x); + try { + progenitor.start(); + progenitor.join(); + for(int i = 0; i < threadCount; i++) { + assertEquals(i, x[i]); + } + } catch(InterruptedException e) { + unexpectedException(); + } + } +} + diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadPoolExecutorTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadPoolExecutorTest.java new file mode 100755 index 0000000..ca4ba78 --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadPoolExecutorTest.java @@ -0,0 +1,1504 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import java.util.concurrent.*; +import junit.framework.*; +import java.util.*; + +public class ThreadPoolExecutorTest extends JSR166TestCase { + public static void main(String[] args) { + junit.textui.TestRunner.run (suite()); + } + public static Test suite() { + return new TestSuite(ThreadPoolExecutorTest.class); + } + + static class ExtendedTPE extends ThreadPoolExecutor { + volatile boolean beforeCalled = false; + volatile boolean afterCalled = false; + volatile boolean terminatedCalled = false; + public ExtendedTPE() { + super(1, 1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new SynchronousQueue<Runnable>()); + } + protected void beforeExecute(Thread t, Runnable r) { + beforeCalled = true; + } + protected void afterExecute(Runnable r, Throwable t) { + afterCalled = true; + } + protected void terminated() { + terminatedCalled = true; + } + } + + /** + * execute successfully executes a runnable + */ + public void testExecute() { + ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + p1.execute(new Runnable() { + public void run() { + try { + Thread.sleep(SHORT_DELAY_MS); + } catch(InterruptedException e){ + threadUnexpectedException(); + } + } + }); + Thread.sleep(SMALL_DELAY_MS); + } catch(InterruptedException e){ + unexpectedException(); + } + joinPool(p1); + } + + /** + * getActiveCount increases but doesn't overestimate, when a + * thread becomes active + */ + public void testGetActiveCount() { + ThreadPoolExecutor p2 = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + assertEquals(0, p2.getActiveCount()); + p2.execute(new MediumRunnable()); + try { + Thread.sleep(SHORT_DELAY_MS); + } catch(Exception e){ + unexpectedException(); + } + assertEquals(1, p2.getActiveCount()); + joinPool(p2); + } + + /** + * prestartCoreThread starts a thread if under corePoolSize, else doesn't + */ + public void testPrestartCoreThread() { + ThreadPoolExecutor p2 = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + assertEquals(0, p2.getPoolSize()); + assertTrue(p2.prestartCoreThread()); + assertEquals(1, p2.getPoolSize()); + assertTrue(p2.prestartCoreThread()); + assertEquals(2, p2.getPoolSize()); + assertFalse(p2.prestartCoreThread()); + assertEquals(2, p2.getPoolSize()); + joinPool(p2); + } + + /** + * prestartAllCoreThreads starts all corePoolSize threads + */ + public void testPrestartAllCoreThreads() { + ThreadPoolExecutor p2 = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + assertEquals(0, p2.getPoolSize()); + p2.prestartAllCoreThreads(); + assertEquals(2, p2.getPoolSize()); + p2.prestartAllCoreThreads(); + assertEquals(2, p2.getPoolSize()); + joinPool(p2); + } + + /** + * getCompletedTaskCount increases, but doesn't overestimate, + * when tasks complete + */ + public void testGetCompletedTaskCount() { + ThreadPoolExecutor p2 = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + assertEquals(0, p2.getCompletedTaskCount()); + p2.execute(new ShortRunnable()); + try { + Thread.sleep(SMALL_DELAY_MS); + } catch(Exception e){ + unexpectedException(); + } + assertEquals(1, p2.getCompletedTaskCount()); + try { p2.shutdown(); } catch(SecurityException ok) { return; } + joinPool(p2); + } + + /** + * getCorePoolSize returns size given in constructor if not otherwise set + */ + public void testGetCorePoolSize() { + ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + assertEquals(1, p1.getCorePoolSize()); + joinPool(p1); + } + + /** + * getKeepAliveTime returns value given in constructor if not otherwise set + */ + public void testGetKeepAliveTime() { + ThreadPoolExecutor p2 = new ThreadPoolExecutor(2, 2, 1000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + assertEquals(1, p2.getKeepAliveTime(TimeUnit.SECONDS)); + joinPool(p2); + } + + + /** + * getThreadFactory returns factory in constructor if not set + */ + public void testGetThreadFactory() { + ThreadFactory tf = new SimpleThreadFactory(); + ThreadPoolExecutor p = new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10), tf, new NoOpREHandler()); + assertSame(tf, p.getThreadFactory()); + joinPool(p); + } + + /** + * setThreadFactory sets the thread factory returned by getThreadFactory + */ + public void testSetThreadFactory() { + ThreadPoolExecutor p = new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + ThreadFactory tf = new SimpleThreadFactory(); + p.setThreadFactory(tf); + assertSame(tf, p.getThreadFactory()); + joinPool(p); + } + + + /** + * setThreadFactory(null) throws NPE + */ + public void testSetThreadFactoryNull() { + ThreadPoolExecutor p = new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + p.setThreadFactory(null); + shouldThrow(); + } catch (NullPointerException success) { + } finally { + joinPool(p); + } + } + + /** + * getRejectedExecutionHandler returns handler in constructor if not set + */ + public void testGetRejectedExecutionHandler() { + RejectedExecutionHandler h = new NoOpREHandler(); + ThreadPoolExecutor p = new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10), h); + assertSame(h, p.getRejectedExecutionHandler()); + joinPool(p); + } + + /** + * setRejectedExecutionHandler sets the handler returned by + * getRejectedExecutionHandler + */ + public void testSetRejectedExecutionHandler() { + ThreadPoolExecutor p = new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + RejectedExecutionHandler h = new NoOpREHandler(); + p.setRejectedExecutionHandler(h); + assertSame(h, p.getRejectedExecutionHandler()); + joinPool(p); + } + + + /** + * setRejectedExecutionHandler(null) throws NPE + */ + public void testSetRejectedExecutionHandlerNull() { + ThreadPoolExecutor p = new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + p.setRejectedExecutionHandler(null); + shouldThrow(); + } catch (NullPointerException success) { + } finally { + joinPool(p); + } + } + + + /** + * getLargestPoolSize increases, but doesn't overestimate, when + * multiple threads active + */ + public void testGetLargestPoolSize() { + ThreadPoolExecutor p2 = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + assertEquals(0, p2.getLargestPoolSize()); + p2.execute(new MediumRunnable()); + p2.execute(new MediumRunnable()); + Thread.sleep(SHORT_DELAY_MS); + assertEquals(2, p2.getLargestPoolSize()); + } catch(Exception e){ + unexpectedException(); + } + joinPool(p2); + } + + /** + * getMaximumPoolSize returns value given in constructor if not + * otherwise set + */ + public void testGetMaximumPoolSize() { + ThreadPoolExecutor p2 = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + assertEquals(2, p2.getMaximumPoolSize()); + joinPool(p2); + } + + /** + * getPoolSize increases, but doesn't overestimate, when threads + * become active + */ + public void testGetPoolSize() { + ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + assertEquals(0, p1.getPoolSize()); + p1.execute(new MediumRunnable()); + assertEquals(1, p1.getPoolSize()); + joinPool(p1); + } + + /** + * getTaskCount increases, but doesn't overestimate, when tasks submitted + */ + public void testGetTaskCount() { + ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + assertEquals(0, p1.getTaskCount()); + p1.execute(new MediumRunnable()); + Thread.sleep(SHORT_DELAY_MS); + assertEquals(1, p1.getTaskCount()); + } catch(Exception e){ + unexpectedException(); + } + joinPool(p1); + } + + /** + * isShutDown is false before shutdown, true after + */ + public void testIsShutdown() { + + ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + assertFalse(p1.isShutdown()); + try { p1.shutdown(); } catch(SecurityException ok) { return; } + assertTrue(p1.isShutdown()); + joinPool(p1); + } + + + /** + * isTerminated is false before termination, true after + */ + public void testIsTerminated() { + ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + assertFalse(p1.isTerminated()); + try { + p1.execute(new MediumRunnable()); + } finally { + try { p1.shutdown(); } catch(SecurityException ok) { return; } + } + try { + assertTrue(p1.awaitTermination(LONG_DELAY_MS, TimeUnit.MILLISECONDS)); + assertTrue(p1.isTerminated()); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * isTerminating is not true when running or when terminated + */ + public void testIsTerminating() { + ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + assertFalse(p1.isTerminating()); + try { + p1.execute(new SmallRunnable()); + assertFalse(p1.isTerminating()); + } finally { + try { p1.shutdown(); } catch(SecurityException ok) { return; } + } + try { + assertTrue(p1.awaitTermination(LONG_DELAY_MS, TimeUnit.MILLISECONDS)); + assertTrue(p1.isTerminated()); + assertFalse(p1.isTerminating()); + } catch(Exception e){ + unexpectedException(); + } + } + + /** + * getQueue returns the work queue, which contains queued tasks + */ + public void testGetQueue() { + BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10); + ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, q); + FutureTask[] tasks = new FutureTask[5]; + for(int i = 0; i < 5; i++){ + tasks[i] = new FutureTask(new MediumPossiblyInterruptedRunnable(), Boolean.TRUE); + p1.execute(tasks[i]); + } + try { + Thread.sleep(SHORT_DELAY_MS); + BlockingQueue<Runnable> wq = p1.getQueue(); + assertSame(q, wq); + assertFalse(wq.contains(tasks[0])); + assertTrue(wq.contains(tasks[4])); + } catch(Exception e) { + unexpectedException(); + } finally { + joinPool(p1); + } + } + + /** + * remove(task) removes queued task, and fails to remove active task + */ + public void testRemove() { + BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10); + ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, q); + FutureTask[] tasks = new FutureTask[5]; + for(int i = 0; i < 5; i++){ + tasks[i] = new FutureTask(new MediumPossiblyInterruptedRunnable(), Boolean.TRUE); + p1.execute(tasks[i]); + } + try { + Thread.sleep(SHORT_DELAY_MS); + assertFalse(p1.remove(tasks[0])); + assertTrue(q.contains(tasks[4])); + assertTrue(q.contains(tasks[3])); + assertTrue(p1.remove(tasks[4])); + assertFalse(p1.remove(tasks[4])); + assertFalse(q.contains(tasks[4])); + assertTrue(q.contains(tasks[3])); + assertTrue(p1.remove(tasks[3])); + assertFalse(q.contains(tasks[3])); + } catch(Exception e) { + unexpectedException(); + } finally { + joinPool(p1); + } + } + + /** + * purge removes cancelled tasks from the queue + */ + public void testPurge() { + ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + FutureTask[] tasks = new FutureTask[5]; + for(int i = 0; i < 5; i++){ + tasks[i] = new FutureTask(new MediumPossiblyInterruptedRunnable(), Boolean.TRUE); + p1.execute(tasks[i]); + } + tasks[4].cancel(true); + tasks[3].cancel(true); + p1.purge(); + long count = p1.getTaskCount(); + assertTrue(count >= 2 && count < 5); + joinPool(p1); + } + + /** + * shutDownNow returns a list containing tasks that were not run + */ + public void testShutDownNow() { + ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + List l; + try { + for(int i = 0; i < 5; i++) + p1.execute(new MediumPossiblyInterruptedRunnable()); + } + finally { + try { + l = p1.shutdownNow(); + } catch (SecurityException ok) { return; } + + } + assertTrue(p1.isShutdown()); + assertTrue(l.size() <= 4); + } + + // Exception Tests + + + /** + * Constructor throws if corePoolSize argument is less than zero + */ + public void testConstructor1() { + try { + new ThreadPoolExecutor(-1,1,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + shouldThrow(); + } + catch (IllegalArgumentException success){} + } + + /** + * Constructor throws if maximumPoolSize is less than zero + */ + public void testConstructor2() { + try { + new ThreadPoolExecutor(1,-1,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + shouldThrow(); + } + catch (IllegalArgumentException success){} + } + + /** + * Constructor throws if maximumPoolSize is equal to zero + */ + public void testConstructor3() { + try { + new ThreadPoolExecutor(1,0,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + shouldThrow(); + } + catch (IllegalArgumentException success){} + } + + /** + * Constructor throws if keepAliveTime is less than zero + */ + public void testConstructor4() { + try { + new ThreadPoolExecutor(1,2,-1L,TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + shouldThrow(); + } + catch (IllegalArgumentException success){} + } + + /** + * Constructor throws if corePoolSize is greater than the maximumPoolSize + */ + public void testConstructor5() { + try { + new ThreadPoolExecutor(2,1,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + shouldThrow(); + } + catch (IllegalArgumentException success){} + } + + /** + * Constructor throws if workQueue is set to null + */ + public void testConstructorNullPointerException() { + try { + new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS,null); + shouldThrow(); + } + catch (NullPointerException success){} + } + + + + /** + * Constructor throws if corePoolSize argument is less than zero + */ + public void testConstructor6() { + try { + new ThreadPoolExecutor(-1,1,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory()); + shouldThrow(); + } catch (IllegalArgumentException success){} + } + + /** + * Constructor throws if maximumPoolSize is less than zero + */ + public void testConstructor7() { + try { + new ThreadPoolExecutor(1,-1,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory()); + shouldThrow(); + } + catch (IllegalArgumentException success){} + } + + /** + * Constructor throws if maximumPoolSize is equal to zero + */ + public void testConstructor8() { + try { + new ThreadPoolExecutor(1,0,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory()); + shouldThrow(); + } + catch (IllegalArgumentException success){} + } + + /** + * Constructor throws if keepAliveTime is less than zero + */ + public void testConstructor9() { + try { + new ThreadPoolExecutor(1,2,-1L,TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory()); + shouldThrow(); + } + catch (IllegalArgumentException success){} + } + + /** + * Constructor throws if corePoolSize is greater than the maximumPoolSize + */ + public void testConstructor10() { + try { + new ThreadPoolExecutor(2,1,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory()); + shouldThrow(); + } + catch (IllegalArgumentException success){} + } + + /** + * Constructor throws if workQueue is set to null + */ + public void testConstructorNullPointerException2() { + try { + new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS,null,new SimpleThreadFactory()); + shouldThrow(); + } + catch (NullPointerException success){} + } + + /** + * Constructor throws if threadFactory is set to null + */ + public void testConstructorNullPointerException3() { + try { + ThreadFactory f = null; + new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),f); + shouldThrow(); + } + catch (NullPointerException success){} + } + + + /** + * Constructor throws if corePoolSize argument is less than zero + */ + public void testConstructor11() { + try { + new ThreadPoolExecutor(-1,1,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler()); + shouldThrow(); + } + catch (IllegalArgumentException success){} + } + + /** + * Constructor throws if maximumPoolSize is less than zero + */ + public void testConstructor12() { + try { + new ThreadPoolExecutor(1,-1,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler()); + shouldThrow(); + } + catch (IllegalArgumentException success){} + } + + /** + * Constructor throws if maximumPoolSize is equal to zero + */ + public void testConstructor13() { + try { + new ThreadPoolExecutor(1,0,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler()); + shouldThrow(); + } + catch (IllegalArgumentException success){} + } + + /** + * Constructor throws if keepAliveTime is less than zero + */ + public void testConstructor14() { + try { + new ThreadPoolExecutor(1,2,-1L,TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler()); + shouldThrow(); + } + catch (IllegalArgumentException success){} + } + + /** + * Constructor throws if corePoolSize is greater than the maximumPoolSize + */ + public void testConstructor15() { + try { + new ThreadPoolExecutor(2,1,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler()); + shouldThrow(); + } + catch (IllegalArgumentException success){} + } + + /** + * Constructor throws if workQueue is set to null + */ + public void testConstructorNullPointerException4() { + try { + new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS,null,new NoOpREHandler()); + shouldThrow(); + } + catch (NullPointerException success){} + } + + /** + * Constructor throws if handler is set to null + */ + public void testConstructorNullPointerException5() { + try { + RejectedExecutionHandler r = null; + new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),r); + shouldThrow(); + } + catch (NullPointerException success){} + } + + + /** + * Constructor throws if corePoolSize argument is less than zero + */ + public void testConstructor16() { + try { + new ThreadPoolExecutor(-1,1,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler()); + shouldThrow(); + } + catch (IllegalArgumentException success){} + } + + /** + * Constructor throws if maximumPoolSize is less than zero + */ + public void testConstructor17() { + try { + new ThreadPoolExecutor(1,-1,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler()); + shouldThrow(); + } + catch (IllegalArgumentException success){} + } + + /** + * Constructor throws if maximumPoolSize is equal to zero + */ + public void testConstructor18() { + try { + new ThreadPoolExecutor(1,0,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler()); + shouldThrow(); + } + catch (IllegalArgumentException success){} + } + + /** + * Constructor throws if keepAliveTime is less than zero + */ + public void testConstructor19() { + try { + new ThreadPoolExecutor(1,2,-1L,TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler()); + shouldThrow(); + } + catch (IllegalArgumentException success){} + } + + /** + * Constructor throws if corePoolSize is greater than the maximumPoolSize + */ + public void testConstructor20() { + try { + new ThreadPoolExecutor(2,1,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler()); + shouldThrow(); + } + catch (IllegalArgumentException success){} + } + + /** + * Constructor throws if workQueue is set to null + */ + public void testConstructorNullPointerException6() { + try { + new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS,null,new SimpleThreadFactory(),new NoOpREHandler()); + shouldThrow(); + } + catch (NullPointerException success){} + } + + /** + * Constructor throws if handler is set to null + */ + public void testConstructorNullPointerException7() { + try { + RejectedExecutionHandler r = null; + new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),r); + shouldThrow(); + } + catch (NullPointerException success){} + } + + /** + * Constructor throws if ThreadFactory is set top null + */ + public void testConstructorNullPointerException8() { + try { + ThreadFactory f = null; + new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),f,new NoOpREHandler()); + shouldThrow(); + } + catch (NullPointerException successdn8){} + } + + + /** + * execute throws RejectedExecutionException + * if saturated. + */ + public void testSaturatedExecute() { + ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1)); + try { + + for(int i = 0; i < 5; ++i){ + p.execute(new MediumRunnable()); + } + shouldThrow(); + } catch(RejectedExecutionException success){} + joinPool(p); + } + + /** + * executor using CallerRunsPolicy runs task if saturated. + */ + public void testSaturatedExecute2() { + RejectedExecutionHandler h = new ThreadPoolExecutor.CallerRunsPolicy(); + ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h); + try { + + TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5]; + for(int i = 0; i < 5; ++i){ + tasks[i] = new TrackedNoOpRunnable(); + } + TrackedLongRunnable mr = new TrackedLongRunnable(); + p.execute(mr); + for(int i = 0; i < 5; ++i){ + p.execute(tasks[i]); + } + for(int i = 1; i < 5; ++i) { + assertTrue(tasks[i].done); + } + try { p.shutdownNow(); } catch(SecurityException ok) { return; } + } catch(RejectedExecutionException ex){ + unexpectedException(); + } finally { + joinPool(p); + } + } + + /** + * executor using DiscardPolicy drops task if saturated. + */ + public void testSaturatedExecute3() { + RejectedExecutionHandler h = new ThreadPoolExecutor.DiscardPolicy(); + ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h); + try { + + TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5]; + for(int i = 0; i < 5; ++i){ + tasks[i] = new TrackedNoOpRunnable(); + } + p.execute(new TrackedLongRunnable()); + for(int i = 0; i < 5; ++i){ + p.execute(tasks[i]); + } + for(int i = 0; i < 5; ++i){ + assertFalse(tasks[i].done); + } + try { p.shutdownNow(); } catch(SecurityException ok) { return; } + } catch(RejectedExecutionException ex){ + unexpectedException(); + } finally { + joinPool(p); + } + } + + /** + * executor using DiscardOldestPolicy drops oldest task if saturated. + */ + public void testSaturatedExecute4() { + RejectedExecutionHandler h = new ThreadPoolExecutor.DiscardOldestPolicy(); + ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h); + try { + p.execute(new TrackedLongRunnable()); + TrackedLongRunnable r2 = new TrackedLongRunnable(); + p.execute(r2); + assertTrue(p.getQueue().contains(r2)); + TrackedNoOpRunnable r3 = new TrackedNoOpRunnable(); + p.execute(r3); + assertFalse(p.getQueue().contains(r2)); + assertTrue(p.getQueue().contains(r3)); + try { p.shutdownNow(); } catch(SecurityException ok) { return; } + } catch(RejectedExecutionException ex){ + unexpectedException(); + } finally { + joinPool(p); + } + } + + /** + * execute throws RejectedExecutionException if shutdown + */ + public void testRejectedExecutionExceptionOnShutdown() { + ThreadPoolExecutor tpe = + new ThreadPoolExecutor(1,1,LONG_DELAY_MS, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(1)); + try { tpe.shutdown(); } catch(SecurityException ok) { return; } + try { + tpe.execute(new NoOpRunnable()); + shouldThrow(); + } catch(RejectedExecutionException success){} + + joinPool(tpe); + } + + /** + * execute using CallerRunsPolicy drops task on shutdown + */ + public void testCallerRunsOnShutdown() { + RejectedExecutionHandler h = new ThreadPoolExecutor.CallerRunsPolicy(); + ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h); + + try { p.shutdown(); } catch(SecurityException ok) { return; } + try { + TrackedNoOpRunnable r = new TrackedNoOpRunnable(); + p.execute(r); + assertFalse(r.done); + } catch(RejectedExecutionException success){ + unexpectedException(); + } finally { + joinPool(p); + } + } + + /** + * execute using DiscardPolicy drops task on shutdown + */ + public void testDiscardOnShutdown() { + RejectedExecutionHandler h = new ThreadPoolExecutor.DiscardPolicy(); + ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h); + + try { p.shutdown(); } catch(SecurityException ok) { return; } + try { + TrackedNoOpRunnable r = new TrackedNoOpRunnable(); + p.execute(r); + assertFalse(r.done); + } catch(RejectedExecutionException success){ + unexpectedException(); + } finally { + joinPool(p); + } + } + + + /** + * execute using DiscardOldestPolicy drops task on shutdown + */ + public void testDiscardOldestOnShutdown() { + RejectedExecutionHandler h = new ThreadPoolExecutor.DiscardOldestPolicy(); + ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h); + + try { p.shutdown(); } catch(SecurityException ok) { return; } + try { + TrackedNoOpRunnable r = new TrackedNoOpRunnable(); + p.execute(r); + assertFalse(r.done); + } catch(RejectedExecutionException success){ + unexpectedException(); + } finally { + joinPool(p); + } + } + + + /** + * execute (null) throws NPE + */ + public void testExecuteNull() { + ThreadPoolExecutor tpe = null; + try { + tpe = new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(10)); + tpe.execute(null); + shouldThrow(); + } catch(NullPointerException success){} + + joinPool(tpe); + } + + /** + * setCorePoolSize of negative value throws IllegalArgumentException + */ + public void testCorePoolSizeIllegalArgumentException() { + ThreadPoolExecutor tpe = null; + try { + tpe = new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(10)); + } catch(Exception e){} + try { + tpe.setCorePoolSize(-1); + shouldThrow(); + } catch(IllegalArgumentException success){ + } finally { + try { tpe.shutdown(); } catch(SecurityException ok) { return; } + } + joinPool(tpe); + } + + /** + * setMaximumPoolSize(int) throws IllegalArgumentException if + * given a value less the core pool size + */ + public void testMaximumPoolSizeIllegalArgumentException() { + ThreadPoolExecutor tpe = null; + try { + tpe = new ThreadPoolExecutor(2,3,LONG_DELAY_MS, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(10)); + } catch(Exception e){} + try { + tpe.setMaximumPoolSize(1); + shouldThrow(); + } catch(IllegalArgumentException success){ + } finally { + try { tpe.shutdown(); } catch(SecurityException ok) { return; } + } + joinPool(tpe); + } + + /** + * setMaximumPoolSize throws IllegalArgumentException + * if given a negative value + */ + public void testMaximumPoolSizeIllegalArgumentException2() { + ThreadPoolExecutor tpe = null; + try { + tpe = new ThreadPoolExecutor(2,3,LONG_DELAY_MS, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(10)); + } catch(Exception e){} + try { + tpe.setMaximumPoolSize(-1); + shouldThrow(); + } catch(IllegalArgumentException success){ + } finally { + try { tpe.shutdown(); } catch(SecurityException ok) { return; } + } + joinPool(tpe); + } + + + /** + * setKeepAliveTime throws IllegalArgumentException + * when given a negative value + */ + public void testKeepAliveTimeIllegalArgumentException() { + ThreadPoolExecutor tpe = null; + try { + tpe = new ThreadPoolExecutor(2,3,LONG_DELAY_MS, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(10)); + } catch(Exception e){} + + try { + tpe.setKeepAliveTime(-1,TimeUnit.MILLISECONDS); + shouldThrow(); + } catch(IllegalArgumentException success){ + } finally { + try { tpe.shutdown(); } catch(SecurityException ok) { return; } + } + joinPool(tpe); + } + + /** + * terminated() is called on termination + */ + public void testTerminated() { + ExtendedTPE tpe = new ExtendedTPE(); + try { tpe.shutdown(); } catch(SecurityException ok) { return; } + assertTrue(tpe.terminatedCalled); + joinPool(tpe); + } + + /** + * beforeExecute and afterExecute are called when executing task + */ + public void testBeforeAfter() { + ExtendedTPE tpe = new ExtendedTPE(); + try { + TrackedNoOpRunnable r = new TrackedNoOpRunnable(); + tpe.execute(r); + Thread.sleep(SHORT_DELAY_MS); + assertTrue(r.done); + assertTrue(tpe.beforeCalled); + assertTrue(tpe.afterCalled); + try { tpe.shutdown(); } catch(SecurityException ok) { return; } + } + catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(tpe); + } + } + + /** + * completed submit of callable returns result + */ + public void testSubmitCallable() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + Future<String> future = e.submit(new StringTask()); + String result = future.get(); + assertSame(TEST_STRING, result); + } + catch (ExecutionException ex) { + unexpectedException(); + } + catch (InterruptedException ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * completed submit of runnable returns successfully + */ + public void testSubmitRunnable() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + Future<?> future = e.submit(new NoOpRunnable()); + future.get(); + assertTrue(future.isDone()); + } + catch (ExecutionException ex) { + unexpectedException(); + } + catch (InterruptedException ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * completed submit of (runnable, result) returns result + */ + public void testSubmitRunnable2() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING); + String result = future.get(); + assertSame(TEST_STRING, result); + } + catch (ExecutionException ex) { + unexpectedException(); + } + catch (InterruptedException ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + + + + + /** + * invokeAny(null) throws NPE + */ + public void testInvokeAny1() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + e.invokeAny(null); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * invokeAny(empty collection) throws IAE + */ + public void testInvokeAny2() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + e.invokeAny(new ArrayList<Callable<String>>()); + } catch (IllegalArgumentException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * invokeAny(c) throws NPE if c has null elements + */ + public void testInvokeAny3() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + l.add(null); + e.invokeAny(l); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * invokeAny(c) throws ExecutionException if no task completes + */ + public void testInvokeAny4() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new NPETask()); + e.invokeAny(l); + } catch (ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * invokeAny(c) returns result of some task + */ + public void testInvokeAny5() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + l.add(new StringTask()); + String result = e.invokeAny(l); + assertSame(TEST_STRING, result); + } catch (ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * invokeAll(null) throws NPE + */ + public void testInvokeAll1() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + e.invokeAll(null); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * invokeAll(empty collection) returns empty collection + */ + public void testInvokeAll2() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>()); + assertTrue(r.isEmpty()); + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * invokeAll(c) throws NPE if c has null elements + */ + public void testInvokeAll3() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + l.add(null); + e.invokeAll(l); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * get of element of invokeAll(c) throws exception on failed task + */ + public void testInvokeAll4() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new NPETask()); + List<Future<String>> result = e.invokeAll(l); + assertEquals(1, result.size()); + for (Iterator<Future<String>> it = result.iterator(); it.hasNext();) + it.next().get(); + } catch(ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * invokeAll(c) returns results of all completed tasks + */ + public void testInvokeAll5() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + l.add(new StringTask()); + List<Future<String>> result = e.invokeAll(l); + assertEquals(2, result.size()); + for (Iterator<Future<String>> it = result.iterator(); it.hasNext();) + assertSame(TEST_STRING, it.next().get()); + } catch (ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + + + /** + * timed invokeAny(null) throws NPE + */ + public void testTimedInvokeAny1() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + e.invokeAny(null, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAny(,,null) throws NPE + */ + public void testTimedInvokeAnyNullTimeUnit() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + e.invokeAny(l, MEDIUM_DELAY_MS, null); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAny(empty collection) throws IAE + */ + public void testTimedInvokeAny2() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + } catch (IllegalArgumentException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAny(c) throws NPE if c has null elements + */ + public void testTimedInvokeAny3() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + l.add(null); + e.invokeAny(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + } catch (NullPointerException success) { + } catch(Exception ex) { + ex.printStackTrace(); + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAny(c) throws ExecutionException if no task completes + */ + public void testTimedInvokeAny4() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new NPETask()); + e.invokeAny(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + } catch(ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAny(c) returns result of some task + */ + public void testTimedInvokeAny5() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + l.add(new StringTask()); + String result = e.invokeAny(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + assertSame(TEST_STRING, result); + } catch (ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAll(null) throws NPE + */ + public void testTimedInvokeAll1() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + e.invokeAll(null, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAll(,,null) throws NPE + */ + public void testTimedInvokeAllNullTimeUnit() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + e.invokeAll(l, MEDIUM_DELAY_MS, null); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAll(empty collection) returns empty collection + */ + public void testTimedInvokeAll2() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + assertTrue(r.isEmpty()); + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAll(c) throws NPE if c has null elements + */ + public void testTimedInvokeAll3() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + l.add(null); + e.invokeAll(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * get of element of invokeAll(c) throws exception on failed task + */ + public void testTimedInvokeAll4() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new NPETask()); + List<Future<String>> result = e.invokeAll(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + assertEquals(1, result.size()); + for (Iterator<Future<String>> it = result.iterator(); it.hasNext();) + it.next().get(); + } catch(ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAll(c) returns results of all completed tasks + */ + public void testTimedInvokeAll5() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + l.add(new StringTask()); + List<Future<String>> result = e.invokeAll(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + assertEquals(2, result.size()); + for (Iterator<Future<String>> it = result.iterator(); it.hasNext();) + assertSame(TEST_STRING, it.next().get()); + } catch (ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAll(c) cancels tasks not completed by timeout + */ + public void testTimedInvokeAll6() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10)); + try { + ArrayList<Callable<String>> l = new ArrayList<Callable<String>>(); + l.add(new StringTask()); + l.add(Executors.callable(new MediumPossiblyInterruptedRunnable(), TEST_STRING)); + l.add(new StringTask()); + List<Future<String>> result = e.invokeAll(l, SHORT_DELAY_MS, TimeUnit.MILLISECONDS); + assertEquals(3, result.size()); + Iterator<Future<String>> it = result.iterator(); + Future<String> f1 = it.next(); + Future<String> f2 = it.next(); + Future<String> f3 = it.next(); + assertTrue(f1.isDone()); + assertTrue(f2.isDone()); + assertTrue(f3.isDone()); + assertFalse(f1.isCancelled()); + assertTrue(f2.isCancelled()); + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + +} diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadTest.java new file mode 100755 index 0000000..a5c63d9 --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadTest.java @@ -0,0 +1,70 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; + +public class ThreadTest extends JSR166TestCase { + public static void main(String[] args) { + junit.textui.TestRunner.run(suite()); + } + + public static Test suite() { + return new TestSuite(ThreadTest.class); + } + + static class MyHandler implements Thread.UncaughtExceptionHandler { + public void uncaughtException(Thread t, Throwable e) { + e.printStackTrace(); + } + } + + /** + * getUncaughtExceptionHandler returns ThreadGroup unless set, + * otherwise returning value of last setUncaughtExceptionHandler. + */ + public void testGetAndSetUncaughtExceptionHandler() { + // these must be done all at once to avoid state + // dependencies across tests + Thread current = Thread.currentThread(); + ThreadGroup tg = current.getThreadGroup(); + MyHandler eh = new MyHandler(); + assertEquals(tg, current.getUncaughtExceptionHandler()); + current.setUncaughtExceptionHandler(eh); + assertEquals(eh, current.getUncaughtExceptionHandler()); + current.setUncaughtExceptionHandler(null); + assertEquals(tg, current.getUncaughtExceptionHandler()); + } + + /** + * getDefaultUncaughtExceptionHandler returns value of last + * setDefaultUncaughtExceptionHandler. + */ + public void testGetAndSetDefaultUncaughtExceptionHandler() { + assertEquals(null, Thread.getDefaultUncaughtExceptionHandler()); + // failure due to securityException is OK. + // Would be nice to explicitly test both ways, but cannot yet. + try { + Thread current = Thread.currentThread(); + ThreadGroup tg = current.getThreadGroup(); + MyHandler eh = new MyHandler(); + Thread.setDefaultUncaughtExceptionHandler(eh); + assertEquals(eh, Thread.getDefaultUncaughtExceptionHandler()); + Thread.setDefaultUncaughtExceptionHandler(null); + } + catch(SecurityException ok) { + } + assertEquals(null, Thread.getDefaultUncaughtExceptionHandler()); + } + + + // How to test actually using UEH within junit? + +} + diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/TimeUnitTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/TimeUnitTest.java new file mode 100755 index 0000000..1a9a04a --- /dev/null +++ b/concurrent/src/test/java/tests/api/java/util/concurrent/TimeUnitTest.java @@ -0,0 +1,333 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +package tests.api.java.util.concurrent; + +import junit.framework.*; +import java.util.concurrent.*; +import java.io.*; + +public class TimeUnitTest extends JSR166TestCase { + public static void main(String[] args) { + junit.textui.TestRunner.run(suite()); + } + + public static Test suite() { + return new TestSuite(TimeUnitTest.class); + } + + /** + * convert correctly converts sample values across the four units + */ + public void testConvert() { + for (long t = 0; t < 10; ++t) { + assertEquals(t, + TimeUnit.SECONDS.convert(t, + TimeUnit.SECONDS)); + assertEquals(t, + TimeUnit.SECONDS.convert(1000 * t, + TimeUnit.MILLISECONDS)); + assertEquals(t, + TimeUnit.SECONDS.convert(1000000 * t, + TimeUnit.MICROSECONDS)); + assertEquals(t, + TimeUnit.SECONDS.convert(1000000000 * t, + TimeUnit.NANOSECONDS)); + assertEquals(1000 * t, + TimeUnit.MILLISECONDS.convert(t, + TimeUnit.SECONDS)); + assertEquals(t, + TimeUnit.MILLISECONDS.convert(t, + TimeUnit.MILLISECONDS)); + assertEquals(t, + TimeUnit.MILLISECONDS.convert(1000 * t, + TimeUnit.MICROSECONDS)); + assertEquals(t, + TimeUnit.MILLISECONDS.convert(1000000 * t, + TimeUnit.NANOSECONDS)); + assertEquals(1000000 * t, + TimeUnit.MICROSECONDS.convert(t, + TimeUnit.SECONDS)); + assertEquals(1000 * t, + TimeUnit.MICROSECONDS.convert(t, + TimeUnit.MILLISECONDS)); + assertEquals(t, + TimeUnit.MICROSECONDS.convert(t, + TimeUnit.MICROSECONDS)); + assertEquals(t, + TimeUnit.MICROSECONDS.convert(1000 * t, + TimeUnit.NANOSECONDS)); + assertEquals(1000000000 * t, + TimeUnit.NANOSECONDS.convert(t, + TimeUnit.SECONDS)); + assertEquals(1000000 * t, + TimeUnit.NANOSECONDS.convert(t, + TimeUnit.MILLISECONDS)); + assertEquals(1000 * t, + TimeUnit.NANOSECONDS.convert(t, + TimeUnit.MICROSECONDS)); + assertEquals(t, + TimeUnit.NANOSECONDS.convert(t, + TimeUnit.NANOSECONDS)); + } + } + + /** + * toNanos correctly converts sample values in different units to + * nanoseconds + */ + public void testToNanos() { + for (long t = 0; t < 10; ++t) { + assertEquals(1000000000 * t, + TimeUnit.SECONDS.toNanos(t)); + + assertEquals(1000000 * t, + TimeUnit.MILLISECONDS.toNanos(t)); + assertEquals(1000 * t, + TimeUnit.MICROSECONDS.toNanos(t)); + assertEquals(t, + TimeUnit.NANOSECONDS.toNanos(t)); + } + } + + /** + * toMicros correctly converts sample values in different units to + * microseconds + */ + public void testToMicros() { + for (long t = 0; t < 10; ++t) { + assertEquals(1000000 * t, + TimeUnit.SECONDS.toMicros(t)); + + assertEquals(1000 * t, + TimeUnit.MILLISECONDS.toMicros(t)); + assertEquals(t, + TimeUnit.MICROSECONDS.toMicros(t)); + assertEquals(t, + TimeUnit.NANOSECONDS.toMicros(t * 1000)); + } + } + + /** + * toMillis correctly converts sample values in different units to + * milliseconds + */ + public void testToMillis() { + for (long t = 0; t < 10; ++t) { + assertEquals(1000 * t, + TimeUnit.SECONDS.toMillis(t)); + + assertEquals(t, + TimeUnit.MILLISECONDS.toMillis(t)); + assertEquals(t, + TimeUnit.MICROSECONDS.toMillis(t * 1000)); + assertEquals(t, + TimeUnit.NANOSECONDS.toMillis(t * 1000000)); + } + } + + /** + * toSeconds correctly converts sample values in different units to + * seconds + */ + public void testToSeconds() { + for (long t = 0; t < 10; ++t) { + assertEquals(t, + TimeUnit.SECONDS.toSeconds(t)); + + assertEquals(t, + TimeUnit.MILLISECONDS.toSeconds(t * 1000)); + assertEquals(t, + TimeUnit.MICROSECONDS.toSeconds(t * 1000000)); + assertEquals(t, + TimeUnit.NANOSECONDS.toSeconds(t * 1000000000)); + } + } + + + /** + * convert saturates positive too-large values to Long.MAX_VALUE + * and negative to LONG.MIN_VALUE + */ + public void testConvertSaturate() { + assertEquals(Long.MAX_VALUE, + TimeUnit.NANOSECONDS.convert(Long.MAX_VALUE / 2, + TimeUnit.SECONDS)); + assertEquals(Long.MIN_VALUE, + TimeUnit.NANOSECONDS.convert(-Long.MAX_VALUE / 4, + TimeUnit.SECONDS)); + } + + /** + * toNanos saturates positive too-large values to Long.MAX_VALUE + * and negative to LONG.MIN_VALUE + */ + public void testToNanosSaturate() { + assertEquals(Long.MAX_VALUE, + TimeUnit.MILLISECONDS.toNanos(Long.MAX_VALUE / 2)); + assertEquals(Long.MIN_VALUE, + TimeUnit.MILLISECONDS.toNanos(-Long.MAX_VALUE / 3)); + } + + + /** + * toString returns string containing common name of unit + */ + public void testToString() { + String s = TimeUnit.SECONDS.toString(); + assertTrue(s.indexOf("ECOND") >= 0); + } + + + /** + * Timed wait without holding lock throws + * IllegalMonitorStateException + */ + public void testTimedWait_IllegalMonitorException() { + //created a new thread with anonymous runnable + + Thread t = new Thread(new Runnable() { + public void run() { + Object o = new Object(); + TimeUnit tu = TimeUnit.MILLISECONDS; + try { + tu.timedWait(o,LONG_DELAY_MS); + threadShouldThrow(); + } + catch (InterruptedException ie) { + threadUnexpectedException(); + } + catch(IllegalMonitorStateException success) { + } + + } + }); + t.start(); + try { + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } catch(Exception e) { + unexpectedException(); + } + } + + /** + * timedWait throws InterruptedException when interrupted + */ + public void testTimedWait() { + Thread t = new Thread(new Runnable() { + public void run() { + Object o = new Object(); + + TimeUnit tu = TimeUnit.MILLISECONDS; + try { + synchronized(o) { + tu.timedWait(o,MEDIUM_DELAY_MS); + } + threadShouldThrow(); + } + catch(InterruptedException success) {} + catch(IllegalMonitorStateException failure) { + threadUnexpectedException(); + } + } + }); + t.start(); + try { + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } catch(Exception e) { + unexpectedException(); + } + } + + + /** + * timedJoin throws InterruptedException when interrupted + */ + public void testTimedJoin() { + Thread t = new Thread(new Runnable() { + public void run() { + TimeUnit tu = TimeUnit.MILLISECONDS; + try { + Thread s = new Thread(new Runnable() { + public void run() { + try { + Thread.sleep(MEDIUM_DELAY_MS); + } catch(InterruptedException success){} + } + }); + s.start(); + tu.timedJoin(s,MEDIUM_DELAY_MS); + threadShouldThrow(); + } + catch(Exception e) {} + } + }); + t.start(); + try { + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } catch(Exception e) { + unexpectedException(); + } + } + + /** + * timedSleep throws InterruptedException when interrupted + */ + public void testTimedSleep() { + //created a new thread with anonymous runnable + + Thread t = new Thread(new Runnable() { + public void run() { + TimeUnit tu = TimeUnit.MILLISECONDS; + try { + tu.sleep(MEDIUM_DELAY_MS); + threadShouldThrow(); + } + catch(InterruptedException success) {} + } + }); + t.start(); + try { + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(); + } catch(Exception e) { + unexpectedException(); + } + } + + /** + * a deserialized serialized unit is equal + */ + public void testSerialization() { + TimeUnit q = TimeUnit.MILLISECONDS; + + try { + ByteArrayOutputStream bout = new ByteArrayOutputStream(10000); + ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout)); + out.writeObject(q); + out.close(); + + ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); + ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin)); + TimeUnit r = (TimeUnit)in.readObject(); + + assertEquals(q.toString(), r.toString()); + } catch(Exception e){ + e.printStackTrace(); + unexpectedException(); + } + } + +} diff --git a/concurrent/src/test/java/tests/concurrent/AllTests.java b/concurrent/src/test/java/tests/concurrent/AllTests.java new file mode 100644 index 0000000..d2ebbeb --- /dev/null +++ b/concurrent/src/test/java/tests/concurrent/AllTests.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package tests.concurrent; + +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * Test suite for the concurrent module + */ +public class AllTests { + + public static void main(String[] args) { + junit.textui.TestRunner.run(suite()); + } + + /** + * Collects all JSR166 unit tests as one suite + */ + public static Test suite ( ) { + TestSuite suite = tests.TestSuiteFactory.createTestSuite("JSR166 Unit Tests"); + + suite.addTest(tests.api.java.util.concurrent.JSR166TestCase.suite()); + + return suite; + } +} |