1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. 7 * 8 * This code is distributed in the hope that it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 * version 2 for more details (a copy is included in the LICENSE file that 12 * accompanied this code). 13 * 14 * You should have received a copy of the GNU General Public License version 15 * 2 along with this work; if not, write to the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 * 18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 * or visit www.oracle.com if you need additional information or have any 20 * questions. 21 */ 22 23 /* 24 * This file is available under and governed by the GNU General Public 25 * License version 2 only, as published by the Free Software Foundation. 26 * However, the following notice accompanied the original version of this 27 * file: 28 * 29 * Written by Doug Lea and Martin Buchholz with assistance from 30 * members of JCP JSR-166 Expert Group and released to the public 31 * domain, as explained at 32 * http://creativecommons.org/publicdomain/zero/1.0/ 33 */ 34 35 /* 36 * @test 37 * @summary Test drainTo failing due to c.add throwing 38 */ 39 40 import java.util.ArrayList; 41 import java.util.List; 42 import java.util.concurrent.DelayQueue; 43 import java.util.concurrent.Delayed; 44 import java.util.concurrent.ArrayBlockingQueue; 45 import java.util.concurrent.BlockingQueue; 46 import java.util.concurrent.LinkedBlockingDeque; 47 import java.util.concurrent.LinkedBlockingQueue; 48 import java.util.concurrent.FutureTask; 49 import java.util.concurrent.PriorityBlockingQueue; 50 import java.util.concurrent.RunnableScheduledFuture; 51 import java.util.concurrent.ScheduledThreadPoolExecutor; 52 import java.util.concurrent.TimeUnit; 53 54 @SuppressWarnings({"unchecked", "rawtypes"}) 55 public class DrainToFails { 56 final int CAPACITY = 10; 57 final int SMALL = 2; 58 test(String[] args)59 void test(String[] args) throws Throwable { 60 testDelayQueue(new DelayQueue()); 61 testDelayQueue(new ScheduledThreadPoolExecutor(1).getQueue()); 62 63 testUnbounded(new LinkedBlockingQueue()); 64 testUnbounded(new LinkedBlockingDeque()); 65 testUnbounded(new PriorityBlockingQueue()); 66 67 testBounded(new LinkedBlockingQueue(CAPACITY)); 68 testBounded(new LinkedBlockingDeque(CAPACITY)); 69 testBounded(new ArrayBlockingQueue(CAPACITY)); 70 } 71 72 static class PDelay 73 extends FutureTask<Void> 74 implements Delayed, RunnableScheduledFuture<Void> { 75 int pseudodelay; PDelay(int i)76 PDelay(int i) { 77 super(new Runnable() { public void run() {}}, null); 78 pseudodelay = i; 79 } compareTo(PDelay other)80 public int compareTo(PDelay other) { 81 return Integer.compare(this.pseudodelay, other.pseudodelay); 82 } compareTo(Delayed y)83 public int compareTo(Delayed y) { 84 return compareTo((PDelay)y); 85 } equals(Object other)86 public boolean equals(Object other) { 87 return (other instanceof PDelay) && 88 this.pseudodelay == ((PDelay)other).pseudodelay; 89 } getDelay(TimeUnit ignore)90 public long getDelay(TimeUnit ignore) { 91 return Integer.MIN_VALUE + pseudodelay; 92 } toString()93 public String toString() { 94 return String.valueOf(pseudodelay); 95 } isPeriodic()96 public boolean isPeriodic() { return false; } 97 } 98 testDelayQueue(final BlockingQueue q)99 void testDelayQueue(final BlockingQueue q) throws Throwable { 100 System.err.println(q.getClass().getSimpleName()); 101 for (int i = 0; i < CAPACITY; i++) 102 q.add(new PDelay(i)); 103 ArrayBlockingQueue q2 = new ArrayBlockingQueue(SMALL); 104 try { 105 q.drainTo(q2, SMALL + 3); 106 fail("should throw"); 107 } catch (IllegalStateException success) { 108 equal(SMALL, q2.size()); 109 equal(new PDelay(0), q2.poll()); 110 equal(new PDelay(1), q2.poll()); 111 check(q2.isEmpty()); 112 for (int i = SMALL; i < CAPACITY; i++) 113 equal(new PDelay(i), q.poll()); 114 equal(0, q.size()); 115 } 116 } 117 testUnbounded(final BlockingQueue q)118 void testUnbounded(final BlockingQueue q) throws Throwable { 119 System.err.println(q.getClass().getSimpleName()); 120 for (int i = 0; i < CAPACITY; i++) 121 q.add(i); 122 ArrayBlockingQueue q2 = new ArrayBlockingQueue(SMALL); 123 try { 124 q.drainTo(q2, 7); 125 fail("should throw"); 126 } catch (IllegalStateException success) { 127 assertContentsInOrder(q2, 0, 1); 128 q2.clear(); 129 equal(q.size(), CAPACITY - SMALL); 130 equal(SMALL, q.peek()); 131 } 132 133 try { 134 q.drainTo(q2); 135 fail("should throw"); 136 } catch (IllegalStateException success) { 137 assertContentsInOrder(q2, 2, 3); 138 equal(q.size(), CAPACITY - 2 * SMALL); 139 for (int i = 2 * SMALL; i < CAPACITY; i++) 140 equal(i, q.poll()); 141 equal(0, q.size()); 142 } 143 } 144 testBounded(final BlockingQueue q)145 void testBounded(final BlockingQueue q) throws Throwable { 146 System.err.println(q.getClass().getSimpleName()); 147 for (int i = 0; i < CAPACITY; i++) 148 q.add(i); 149 List<Thread> putters = new ArrayList<>(); 150 for (int i = 0; i < 4; i++) { 151 Thread putter = new Thread(putter(q, 42 + i)); 152 putters.add(putter); 153 putter.setDaemon(true); 154 putter.start(); 155 } 156 ArrayBlockingQueue q2 = new ArrayBlockingQueue(SMALL); 157 try { 158 q.drainTo(q2, 7); 159 fail("should throw"); 160 } catch (IllegalStateException success) { 161 while (q.size() < CAPACITY) 162 Thread.yield(); 163 assertContentsInOrder(q2, 0, 1); 164 q2.clear(); 165 } 166 167 try { 168 q.drainTo(q2); 169 fail("should throw"); 170 } catch (IllegalStateException success) { 171 for (Thread putter : putters) { 172 putter.join(2000L); 173 check(! putter.isAlive()); 174 } 175 assertContentsInOrder(q2, 2, 3); 176 for (int i = 2 * SMALL; i < CAPACITY; i++) 177 equal(i, q.poll()); 178 equal(4, q.size()); 179 check(q.contains(42)); 180 check(q.contains(43)); 181 check(q.contains(44)); 182 check(q.contains(45)); 183 } 184 } 185 putter(final BlockingQueue q, final int elt)186 Runnable putter(final BlockingQueue q, final int elt) { 187 return new Runnable() { 188 public void run() { 189 try { q.put(elt); } 190 catch (Throwable t) { unexpected(t); }}}; 191 } 192 193 void assertContentsInOrder(Iterable it, Object... contents) { 194 int i = 0; 195 for (Object e : it) 196 equal(contents[i++], e); 197 equal(contents.length, i); 198 } 199 200 //--------------------- Infrastructure --------------------------- 201 volatile int passed = 0, failed = 0; 202 void pass() {passed++;} 203 void fail() {failed++; Thread.dumpStack();} 204 void fail(String msg) {System.err.println(msg); fail();} 205 void unexpected(Throwable t) {failed++; t.printStackTrace();} 206 void check(boolean cond) {if (cond) pass(); else fail();} 207 void equal(Object x, Object y) { 208 if (x == null ? y == null : x.equals(y)) pass(); 209 else fail(x + " not equal to " + y);} 210 public static void main(String[] args) throws Throwable { 211 new DrainToFails().instanceMain(args);} 212 public void instanceMain(String[] args) throws Throwable { 213 try {test(args);} catch (Throwable t) {unexpected(t);} 214 System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); 215 if (failed > 0) throw new AssertionError("Some tests failed");} 216 } 217