ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/DequeBash.java
Revision: 1.15
Committed: Sun Oct 23 02:21:56 2016 UTC (7 years, 6 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.14: +2 -1 lines
Log Message:
fix deprecation warning from Class#newInstance

File Contents

# Content
1 /*
2 * Written by Josh Bloch of Google Inc. and released to the public domain,
3 * as explained at http://creativecommons.org/publicdomain/zero/1.0/.
4 */
5
6 import java.io.*;
7 import java.util.*;
8
9 /**
10 * Interface-based Deque tester. This test currently makes three
11 * assumptions about the implementation under test:
12 *
13 * 1) It has no size limitation.
14 * 2) It implements Serializable.
15 * 3) It has a conventional (Collection) constructor.
16 *
17 * All of these assumptions could be relaxed.
18 */
19 public class DequeBash {
20 static int seed = 7;
21 static int nextTail = 0;
22 static int nextHead = -1;
23 static int size() { return nextTail - nextHead - 1; }
24
25 static int random() {
26 int r = seed;
27 r ^= r << 13; // xorshift
28 r ^= r >>> 17;
29 return seed = r ^ (r << 5);
30 }
31
32 static int random(int bound) {
33 return (random() & 0x7fffffff) % bound;
34 }
35
36 public static void main(String[] args) throws Exception {
37 Class<?> cls = Class.forName(args[0]);
38 long startTime = System.nanoTime();
39 for (int j = 0; j < 200; ++j) {
40 @SuppressWarnings("unchecked")
41 Deque<Integer> deque =
42 (Deque<Integer>) cls.getConstructor().newInstance();
43 nextTail = 0;
44 nextHead = -1;
45 mainTest(deque, (random() & ((1 << 20) - 1)));
46 if (deque.isEmpty()) System.out.print(" ");
47 if ((j % 10) == 9) System.out.print(".");
48 }
49 long now = System.nanoTime();
50 long elapsedTimeMillis = (now - startTime) / (1000L * 1000L);
51 System.out.printf("\ntotal time %d ms\n", elapsedTimeMillis);
52
53 }
54
55 static void mainTest(Deque<Integer> deque, int n) throws Exception {
56 /*
57 * Perform a random sequence of operations, keeping contiguous
58 * sequence of integers on the deque.
59 */
60 for (int i = 0; i < n; i++) {
61 sizeTests(deque);
62 randomOp(deque);
63
64 // Test iterator occasionally
65 if ((i & 1023) == 0) {
66 testIter(deque);
67 testDescendingIter(deque);
68 }
69
70 // Test serialization and copying
71 if ((i & 4095) == 0) {
72 testEqual(deque, serialClone(deque));
73 testEqual(deque, copyConstructorClone(deque));
74 }
75
76 // Test fancy removal stuff once in a blue moon
77 if ((i & 8191) == 0)
78 testRemove(deque);
79 }
80
81 // Stupid tests for clear, toString
82 deque.clear();
83 testEmpty(deque);
84 Collection<Integer> c = Arrays.asList(1, 2, 3);
85 deque.addAll(c);
86 if (!deque.toString().equals("[1, 2, 3]"))
87 throw new Exception("Deque.toString(): " + deque.toString());
88 }
89
90 static void testIter(Deque<Integer> deque) throws Exception {
91 int next = nextHead + 1;
92 int count = 0;
93 for (int j : deque) {
94 if (j != next++)
95 throw new Exception("Element "+ j + " != " + (next-1));
96 count++;
97 }
98 if (count != size())
99 throw new Exception("Count " + count + " != " + size());
100 }
101
102 static void testDescendingIter(Deque<Integer> deque) throws Exception {
103 int next = deque.size() + nextHead;
104 int count = 0;
105 for (Iterator<Integer> it = deque.descendingIterator(); it.hasNext();) {
106 int j = it.next();
107 if (j != next--)
108 throw new Exception("Element "+ j + " != " + (next-1));
109 count++;
110 }
111 if (count != size())
112 throw new Exception("Count " + count + " != " + size());
113 }
114
115 static void sizeTests(Deque<Integer> deque) throws Exception {
116 if (deque.size() != size())
117 throw new Exception("Size: " + deque.size() +
118 ", expecting " + size());
119 if (deque.isEmpty() != (size() == 0))
120 throw new Exception(
121 "IsEmpty " + deque.isEmpty() + ", size " + size());
122 // Check head and tail
123 if (size() == 0)
124 testEmpty(deque);
125 else
126 nonEmptyTest(deque);
127
128 }
129
130 static void nonEmptyTest(Deque<Integer> deque) throws Exception {
131 if (deque.getFirst() != nextHead + 1)
132 throw new Exception("getFirst got: " +
133 deque.getFirst() + " expecting " + (nextHead + 1));
134 if (deque.element() != nextHead + 1)
135 throw new Exception("element got: " + deque.element() +
136 " expecting " + (nextHead + 1));
137 if (deque.peekFirst() != nextHead + 1)
138 throw new Exception("peekFirst got: "+deque.peekFirst() +
139 " expecting " + (nextHead + 1));
140 if (deque.peek() != nextHead + 1)
141 throw new Exception("peek got: " + deque.peek() +
142 " expecting " + (nextHead + 1));
143
144 if (deque.peekLast() != nextTail - 1)
145 throw new Exception("peekLast got: " + deque.peekLast() +
146 " expecting " + (nextTail - 1));
147 if (deque.getLast() != nextTail - 1)
148 throw new Exception("getLast got: " +
149 deque.getLast() + " expecting " + (nextTail - 1));
150 }
151
152 static void randomOp(Deque<Integer> deque) throws Exception {
153
154 // Perform a random operation
155 switch (random() & 3) {
156 case 0:
157 switch (random() & 3) {
158 case 0: deque.addLast(nextTail++); break;
159 case 1: deque.offerLast(nextTail++); break;
160 case 2: deque.offer(nextTail++); break;
161 case 3: deque.add(nextTail++); break;
162 default: throw new Exception("How'd we get here");
163 }
164 break;
165 case 1:
166 if (size() == 0) {
167 int result = 666;
168 boolean threw = false;
169 try {
170 switch (random(3)) {
171 case 0: result = deque.removeFirst(); break;
172 case 1: result = deque.remove(); break;
173 case 2: result = deque.pop(); break;
174 default: throw new Exception("How'd we get here");
175 }
176 } catch (NoSuchElementException e) {
177 threw = true;
178 }
179 if (!threw)
180 throw new Exception("Remove-no exception: " + result);
181 } else { // deque nonempty
182 int result = -1;
183 switch (random(5)) {
184 case 0: result = deque.removeFirst(); break;
185 case 1: result = deque.remove(); break;
186 case 2: result = deque.pop(); break;
187 case 3: result = deque.pollFirst(); break;
188 case 4: result = deque.poll(); break;
189 default: throw new Exception("How'd we get here");
190 }
191 if (result != ++nextHead)
192 throw new Exception(
193 "Removed "+ result + " expecting "+(nextHead - 1));
194 }
195 break;
196 case 2:
197 switch (random(3)) {
198 case 0: deque.addFirst(nextHead--); break;
199 case 1: deque.offerFirst(nextHead--); break;
200 case 2: deque.push(nextHead--); break;
201 default: throw new Exception("How'd we get here");
202 }
203 break;
204 case 3:
205 if (size() == 0) {
206 int result = -1;
207 boolean threw = false;
208 try {
209 result = deque.removeLast();
210 } catch (NoSuchElementException e) {
211 threw = true;
212 }
213 if (!threw)
214 throw new Exception("Remove-no exception: " + result);
215 } else { // deque nonempty
216 int result = ((random() & 1) == 0 ?
217 deque.removeLast() : deque.pollLast());
218 if (result != --nextTail)
219 throw new Exception(
220 "Removed "+ result + " expecting "+(nextTail + 1));
221 }
222 break;
223 default:
224 throw new Exception("How'd we get here");
225 }
226 }
227
228 private static void testEqual(Deque<Integer> d1, Deque<Integer> d2)
229 throws Exception
230 {
231 if (d1.size() != d2.size())
232 throw new Exception("Size " + d1.size() + " != " + d2.size());
233 Iterator<Integer> it = d2.iterator();
234 for (int i : d1) {
235 int j = it.next();
236 if (j != i)
237 throw new Exception("Element " + j + " != " + i);
238 }
239
240 for (int i : d1)
241 if (!d2.contains(i))
242 throw new Exception("d2 doesn't contain " + i);
243 for (int i : d2)
244 if (!d1.contains(i))
245 throw new Exception("d2 doesn't contain " + i);
246
247 if (d1.contains(Integer.MIN_VALUE))
248 throw new Exception("d2 contains Integer.MIN_VALUE");
249 if (d2.contains(Integer.MIN_VALUE))
250 throw new Exception("d2 contains Integer.MIN_VALUE");
251 if (d1.contains(null))
252 throw new Exception("d1 contains null");
253 if (d2.contains(null))
254 throw new Exception("d2 contains null");
255
256 if (!d1.containsAll(d2))
257 throw new Exception("d1 doesn't contain all of d2");
258 if (!d2.containsAll(d1))
259 throw new Exception("d2 doesn't contain all of d1");
260 Collection<Integer> c = Collections.singleton(Integer.MIN_VALUE);
261 if (d1.containsAll(c))
262 throw new Exception("d1 contains all of {Integer.MIN_VALUE }");
263 if (d2.containsAll(c))
264 throw new Exception("d2 contains all of {Integer.MIN_VALUE }");
265 }
266
267 @SuppressWarnings("unchecked")
268 private static <T> T copyConstructorClone(T o) throws Exception {
269 return (T) o.getClass().getConstructor(Collection.class).newInstance(o);
270 }
271
272 @SuppressWarnings("unchecked")
273 private static <T> T serialClone(T o) throws Exception {
274 ByteArrayOutputStream bos = new ByteArrayOutputStream();
275 ObjectOutputStream oos = new ObjectOutputStream(bos);
276 oos.writeObject(o);
277 oos.flush();
278 oos.close();
279 ByteArrayInputStream bin =
280 new ByteArrayInputStream(bos.toByteArray());
281 ObjectInputStream ois = new ObjectInputStream(bin);
282 return (T) ois.readObject();
283 }
284
285 private static void testRemove(Deque<Integer> deque) throws Exception {
286 Deque<Integer> copy = ((random() & 1) == 0) ?
287 copyConstructorClone(deque) :
288 serialClone(deque);
289
290 int numRemoved = 0;
291 for (Iterator<Integer> it = copy.iterator(); it.hasNext(); ) {
292 if ((it.next() & 1) == 0) {
293 it.remove();
294 numRemoved++;
295 }
296 }
297
298 if (copy.size() + numRemoved != size())
299 throw new Exception((copy.size() + numRemoved) + " != " + size());
300 for (int i : copy)
301 if ((i & 1) == 0)
302 throw new Exception("Even number still present: " + i);
303
304 List<Integer> elements = Arrays.asList(copy.toArray(new Integer[0]));
305 Collections.shuffle(elements);
306 for (int e : elements) {
307 if (!copy.contains(e))
308 throw new Exception(e + " missing.");
309
310 boolean removed = false;
311 switch (random(3)) {
312 case 0: removed = copy.remove(e); break;
313 case 1: removed = copy.removeFirstOccurrence(e); break;
314 case 2: removed = copy.removeLastOccurrence(e); break;
315 default: throw new Exception("How'd we get here");
316 }
317 if (!removed)
318 throw new Exception(e + " not removed.");
319
320 if (copy.contains(e))
321 throw new Exception(e + " present after removal.");
322 }
323
324 testEmpty(copy);
325
326 copy = copyConstructorClone(deque);
327 copy.retainAll(deque);
328 testEqual(deque, copy);
329 copy.removeAll(deque);
330 testEmpty(copy);
331 }
332
333 static boolean checkedThrows;
334
335 private static void testEmpty(Deque<Integer> deque) throws Exception {
336 if (!deque.isEmpty())
337 throw new Exception("Deque isn't empty");
338 if (deque.size() != 0)
339 throw new Exception("Deque size isn't zero");
340 if (!(deque.pollFirst() == null))
341 throw new Exception("pollFirst lies");
342 if (!(deque.poll() == null))
343 throw new Exception("poll lies");
344 if (!(deque.peekFirst() == null))
345 throw new Exception("peekFirst lies");
346 if (!(deque.peek() == null))
347 throw new Exception("peek lies");
348 if (!(deque.pollLast() == null))
349 throw new Exception("pollLast lies");
350 if (!(deque.peekLast() == null))
351 throw new Exception("peekLast lies");
352
353 if (!checkedThrows) {
354 checkedThrows = true;
355 boolean threw = false;
356 int result = 666;
357 try {
358 result = ((random() & 1) == 0 ?
359 deque.getFirst() : deque.element());
360 } catch (NoSuchElementException e) {
361 threw = true;
362 }
363 if (!threw)
364 throw new Exception("getFirst-no exception: "+result);
365 threw = false;
366 try {
367 result = deque.getLast();
368 } catch (NoSuchElementException e) {
369 threw = true;
370 }
371 if (!threw)
372 throw new Exception("getLast-no exception: "+result);
373 }
374
375 }
376 }