blob: 315ae73f44202d0b85314f9208d989ca00c7bb06 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24/*
25 * @test
26 * @bug 6324846
27 * @summary Deque implementations must behave isomorphically
28 * @author Martin Buchholz
29 */
30
31import java.util.*;
32import java.util.concurrent.*;
33
34public class ChorusLine {
35 private interface Tweaker {
36 void run(Deque<Integer> deq);
37 }
38
39 private final static Tweaker[] tweakers = {
40 new Tweaker() { public void run(Deque<Integer> deq) {
41 for (int i = 0; i < 7; i++)
42 deq.addLast(i);
43 deq.removeFirst();
44 deq.removeFirst();
45 deq.addLast(7);
46 deq.addLast(8);
47 Iterator<Integer> it = deq.descendingIterator();
48 equal(it.next(), 8);
49 it.remove();
50
51 try {it.remove();}
52 catch (IllegalStateException e) {pass();}
53 catch (Throwable t) {unexpected(t);}
54
55 deq.addLast(9);
56 it = deq.descendingIterator();
57 equal(it.next(), 9);
58 equal(it.next(), 7);
59 it.remove();
60
61 try {it.remove();}
62 catch (IllegalStateException e) {pass();}
63 catch (Throwable t) {unexpected(t);}
64
65 equal(it.next(), 6);
66
67 System.out.println(deq);
68 }},
69 new Tweaker() { public void run(Deque<Integer> deq) {
70 deq.clear();
71 check(deq.isEmpty());
72 check(deq.size() == 0);
73 check(! deq.iterator().hasNext());
74 check(! deq.descendingIterator().hasNext());
75
76 try {deq.iterator().next(); fail();}
77 catch (NoSuchElementException e) {pass();}
78 catch (Throwable t) {unexpected(t);}
79
80 try {deq.descendingIterator().next(); fail();}
81 catch (NoSuchElementException e) {pass();}
82 catch (Throwable t) {unexpected(t);}
83 }},
84 new Tweaker() { public void run(Deque<Integer> deq) {
85 for (int i = 0; i < 11; i++)
86 deq.add(i);
87 Iterator<Integer> it = deq.iterator();
88 equal(it.next(), 0);
89 equal(it.next(), 1);
90 it.remove();
91 deq.addFirst(-1);
92 deq.addFirst(-2);
93 it = deq.iterator();
94 equal(it.next(), -2);
95 equal(it.next(), -1);
96 equal(it.next(), 0);
97 it.remove();
98
99 it = deq.descendingIterator();
100
101 try {it.remove(); fail();}
102 catch (IllegalStateException e) {pass();}
103 catch (Throwable t) {unexpected(t);}
104
105 equal(it.next(), 10);
106 it.remove();
107
108 try {it.remove(); fail();}
109 catch (IllegalStateException e) {pass();}
110 catch (Throwable t) {unexpected(t);}
111
112 equal(it.next(), 9);
113 equal(it.next(), 8);
114 it.remove();
115 System.out.println(deq);
116 }},
117 new Tweaker() { public void run(Deque<Integer> deq) {
118 while (deq.size() > 1) {
119 Iterator<Integer> it = deq.iterator();
120 it.next(); it.remove();
121 it = deq.descendingIterator();
122 it.next(); it.remove();
123 }
124 System.out.println(deq);
125 }}};
126
127 private static void realMain(String[] args) throws Throwable {
128 Collection<Deque<Integer>> deqs = new ArrayDeque<Deque<Integer>>(3);
129 deqs.add(new ArrayDeque<Integer>());
130 deqs.add(new LinkedList<Integer>());
131 deqs.add(new LinkedBlockingDeque<Integer>());
132
133 equal(deqs);
134
135 for (Tweaker tweaker : tweakers) {
136 for (Deque<Integer> deq : deqs)
137 tweaker.run(deq);
138 equal(deqs);
139 }
140 }
141
142 private static void equal(Iterable<Deque<Integer>> deqs) {
143 Deque<Integer> prev = null;
144 for (Deque<Integer> deq : deqs) {
145 if (prev != null) {
146 equal(prev.isEmpty(), deq.isEmpty());
147 equal(prev.size(), deq.size());
148 equal(prev.toString(), deq.toString());
149 }
150 prev = deq;
151 }
152
153 Deque<Iterator<Integer>> its = new ArrayDeque<Iterator<Integer>>();
154 for (Deque<Integer> deq : deqs)
155 its.addLast(deq.iterator());
156 equal(its);
157
158 Deque<Iterator<Integer>> dits = new ArrayDeque<Iterator<Integer>>();
159 for (Deque<Integer> deq : deqs)
160 dits.addLast(deq.descendingIterator());
161 equal(dits);
162 }
163
164 private static void equal(Deque<Iterator<Integer>> its) {
165 Iterator<Integer> it0 = its.remove();
166 while (it0.hasNext()) {
167 Integer i = it0.next();
168 for (Iterator<Integer> it : its)
169 equal(it.next(), i);
170 }
171 for (Iterator<Integer> it : its) {
172 check(! it.hasNext());
173
174 try {it.next(); fail();}
175 catch (NoSuchElementException e) {pass();}
176 catch (Throwable t) {unexpected(t);}
177 }
178 }
179
180 //--------------------- Infrastructure ---------------------------
181 static volatile int passed = 0, failed = 0;
182 static void pass() {passed++;}
183 static void fail() {failed++; Thread.dumpStack();}
184 static void fail(String msg) {System.out.println(msg); fail();}
185 static void unexpected(Throwable t) {failed++; t.printStackTrace();}
186 static void check(boolean cond) {if (cond) pass(); else fail();}
187 static void equal(Object x, Object y) {
188 if (x == null ? y == null : x.equals(y)) pass();
189 else fail(x + " not equal to " + y);}
190 public static void main(String[] args) throws Throwable {
191 try {realMain(args);} catch (Throwable t) {unexpected(t);}
192 System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
193 if (failed > 0) throw new AssertionError("Some tests failed");}
194}