1 /*
2  * Written by Doug Lea with assistance from members of JCP JSR-166
3  * Expert Group and released to the public domain, as explained at
4  * http://creativecommons.org/publicdomain/zero/1.0/
5  * Other contributors include Andrew Wright, Jeffrey Hayes,
6  * Pat Fisher, Mike Judd.
7  */
8 
9 package jsr166;
10 
11 import junit.framework.*;
12 import java.util.ArrayList;
13 import java.util.Arrays;
14 import java.util.Collection;
15 import java.util.Collections;
16 import java.util.Iterator;
17 import java.util.NoSuchElementException;
18 import java.util.Set;
19 import java.util.Vector;
20 import java.util.concurrent.CopyOnWriteArraySet;
21 
22 public class CopyOnWriteArraySetTest extends JSR166TestCase {
23 
populatedSet(int n)24     static CopyOnWriteArraySet<Integer> populatedSet(int n) {
25         CopyOnWriteArraySet<Integer> a = new CopyOnWriteArraySet<Integer>();
26         assertTrue(a.isEmpty());
27         for (int i = 0; i < n; i++)
28             a.add(i);
29         assertFalse(a.isEmpty());
30         assertEquals(n, a.size());
31         return a;
32     }
33 
populatedSet(Integer[] elements)34     static CopyOnWriteArraySet populatedSet(Integer[] elements) {
35         CopyOnWriteArraySet<Integer> a = new CopyOnWriteArraySet<Integer>();
36         assertTrue(a.isEmpty());
37         for (int i = 0; i < elements.length; i++)
38             a.add(elements[i]);
39         assertFalse(a.isEmpty());
40         assertEquals(elements.length, a.size());
41         return a;
42     }
43 
44     /**
45      * Default-constructed set is empty
46      */
testConstructor()47     public void testConstructor() {
48         CopyOnWriteArraySet a = new CopyOnWriteArraySet();
49         assertTrue(a.isEmpty());
50     }
51 
52     /**
53      * Collection-constructed set holds all of its elements
54      */
testConstructor3()55     public void testConstructor3() {
56         Integer[] ints = new Integer[SIZE];
57         for (int i = 0; i < SIZE-1; ++i)
58             ints[i] = new Integer(i);
59         CopyOnWriteArraySet a = new CopyOnWriteArraySet(Arrays.asList(ints));
60         for (int i = 0; i < SIZE; ++i)
61             assertTrue(a.contains(ints[i]));
62     }
63 
64     /**
65      * addAll adds each element from the given collection
66      */
testAddAll()67     public void testAddAll() {
68         CopyOnWriteArraySet full = populatedSet(3);
69         Vector v = new Vector();
70         v.add(three);
71         v.add(four);
72         v.add(five);
73         full.addAll(v);
74         assertEquals(6, full.size());
75     }
76 
77     /**
78      * addAll adds each element from the given collection that did not
79      * already exist in the set
80      */
testAddAll2()81     public void testAddAll2() {
82         CopyOnWriteArraySet full = populatedSet(3);
83         Vector v = new Vector();
84         v.add(three);
85         v.add(four);
86         v.add(one); // will not add this element
87         full.addAll(v);
88         assertEquals(5, full.size());
89     }
90 
91     /**
92      * add will not add the element if it already exists in the set
93      */
testAdd2()94     public void testAdd2() {
95         CopyOnWriteArraySet full = populatedSet(3);
96         full.add(one);
97         assertEquals(3, full.size());
98     }
99 
100     /**
101      * add adds the element when it does not exist in the set
102      */
testAdd3()103     public void testAdd3() {
104         CopyOnWriteArraySet full = populatedSet(3);
105         full.add(three);
106         assertTrue(full.contains(three));
107     }
108 
109     /**
110      * clear removes all elements from the set
111      */
testClear()112     public void testClear() {
113         CopyOnWriteArraySet full = populatedSet(3);
114         full.clear();
115         assertEquals(0, full.size());
116     }
117 
118     /**
119      * contains returns true for added elements
120      */
testContains()121     public void testContains() {
122         CopyOnWriteArraySet full = populatedSet(3);
123         assertTrue(full.contains(one));
124         assertFalse(full.contains(five));
125     }
126 
127     /**
128      * Sets with equal elements are equal
129      */
testEquals()130     public void testEquals() {
131         CopyOnWriteArraySet a = populatedSet(3);
132         CopyOnWriteArraySet b = populatedSet(3);
133         assertTrue(a.equals(b));
134         assertTrue(b.equals(a));
135         assertEquals(a.hashCode(), b.hashCode());
136         a.add(m1);
137         assertFalse(a.equals(b));
138         assertFalse(b.equals(a));
139         b.add(m1);
140         assertTrue(a.equals(b));
141         assertTrue(b.equals(a));
142         assertEquals(a.hashCode(), b.hashCode());
143     }
144 
145     /**
146      * containsAll returns true for collections with subset of elements
147      */
testContainsAll()148     public void testContainsAll() {
149         CopyOnWriteArraySet full = populatedSet(3);
150         Vector v = new Vector();
151         v.add(one);
152         v.add(two);
153         assertTrue(full.containsAll(v));
154         v.add(six);
155         assertFalse(full.containsAll(v));
156     }
157 
158     /**
159      * isEmpty is true when empty, else false
160      */
testIsEmpty()161     public void testIsEmpty() {
162         CopyOnWriteArraySet empty = new CopyOnWriteArraySet();
163         CopyOnWriteArraySet full = populatedSet(3);
164         assertTrue(empty.isEmpty());
165         assertFalse(full.isEmpty());
166     }
167 
168     /**
169      * iterator() returns an iterator containing the elements of the
170      * set in insertion order
171      */
testIterator()172     public void testIterator() {
173         Collection empty = new CopyOnWriteArraySet();
174         assertFalse(empty.iterator().hasNext());
175         try {
176             empty.iterator().next();
177             shouldThrow();
178         } catch (NoSuchElementException success) {}
179 
180         Integer[] elements = new Integer[SIZE];
181         for (int i = 0; i < SIZE; i++)
182             elements[i] = i;
183         Collections.shuffle(Arrays.asList(elements));
184         Collection<Integer> full = populatedSet(elements);
185 
186         Iterator it = full.iterator();
187         for (int j = 0; j < SIZE; j++) {
188             assertTrue(it.hasNext());
189             assertEquals(elements[j], it.next());
190         }
191         assertFalse(it.hasNext());
192         try {
193             it.next();
194             shouldThrow();
195         } catch (NoSuchElementException success) {}
196     }
197 
198     /**
199      * iterator remove is unsupported
200      */
testIteratorRemove()201     public void testIteratorRemove() {
202         CopyOnWriteArraySet full = populatedSet(3);
203         Iterator it = full.iterator();
204         it.next();
205         try {
206             it.remove();
207             shouldThrow();
208         } catch (UnsupportedOperationException success) {}
209     }
210 
211     /**
212      * toString holds toString of elements
213      */
testToString()214     public void testToString() {
215         assertEquals("[]", new CopyOnWriteArraySet().toString());
216         CopyOnWriteArraySet full = populatedSet(3);
217         String s = full.toString();
218         for (int i = 0; i < 3; ++i)
219             assertTrue(s.contains(String.valueOf(i)));
220         assertEquals(new ArrayList(full).toString(),
221                      full.toString());
222     }
223 
224     /**
225      * removeAll removes all elements from the given collection
226      */
testRemoveAll()227     public void testRemoveAll() {
228         CopyOnWriteArraySet full = populatedSet(3);
229         Vector v = new Vector();
230         v.add(one);
231         v.add(two);
232         full.removeAll(v);
233         assertEquals(1, full.size());
234     }
235 
236     /**
237      * remove removes an element
238      */
testRemove()239     public void testRemove() {
240         CopyOnWriteArraySet full = populatedSet(3);
241         full.remove(one);
242         assertFalse(full.contains(one));
243         assertEquals(2, full.size());
244     }
245 
246     /**
247      * size returns the number of elements
248      */
testSize()249     public void testSize() {
250         CopyOnWriteArraySet empty = new CopyOnWriteArraySet();
251         CopyOnWriteArraySet full = populatedSet(3);
252         assertEquals(3, full.size());
253         assertEquals(0, empty.size());
254     }
255 
256     /**
257      * toArray() returns an Object array containing all elements from
258      * the set in insertion order
259      */
testToArray()260     public void testToArray() {
261         Object[] a = new CopyOnWriteArraySet().toArray();
262         assertTrue(Arrays.equals(new Object[0], a));
263         assertSame(Object[].class, a.getClass());
264 
265         Integer[] elements = new Integer[SIZE];
266         for (int i = 0; i < SIZE; i++)
267             elements[i] = i;
268         Collections.shuffle(Arrays.asList(elements));
269         Collection<Integer> full = populatedSet(elements);
270 
271         assertTrue(Arrays.equals(elements, full.toArray()));
272         assertSame(Object[].class, full.toArray().getClass());
273     }
274 
275     /**
276      * toArray(Integer array) returns an Integer array containing all
277      * elements from the set in insertion order
278      */
testToArray2()279     public void testToArray2() {
280         Collection empty = new CopyOnWriteArraySet();
281         Integer[] a;
282 
283         a = new Integer[0];
284         assertSame(a, empty.toArray(a));
285 
286         a = new Integer[SIZE/2];
287         Arrays.fill(a, 42);
288         assertSame(a, empty.toArray(a));
289         assertNull(a[0]);
290         for (int i = 1; i < a.length; i++)
291             assertEquals(42, (int) a[i]);
292 
293         Integer[] elements = new Integer[SIZE];
294         for (int i = 0; i < SIZE; i++)
295             elements[i] = i;
296         Collections.shuffle(Arrays.asList(elements));
297         Collection<Integer> full = populatedSet(elements);
298 
299         Arrays.fill(a, 42);
300         assertTrue(Arrays.equals(elements, full.toArray(a)));
301         for (int i = 0; i < a.length; i++)
302             assertEquals(42, (int) a[i]);
303         assertSame(Integer[].class, full.toArray(a).getClass());
304 
305         a = new Integer[SIZE];
306         Arrays.fill(a, 42);
307         assertSame(a, full.toArray(a));
308         assertTrue(Arrays.equals(elements, a));
309 
310         a = new Integer[2*SIZE];
311         Arrays.fill(a, 42);
312         assertSame(a, full.toArray(a));
313         assertTrue(Arrays.equals(elements, Arrays.copyOf(a, SIZE)));
314         assertNull(a[SIZE]);
315         for (int i = SIZE + 1; i < a.length; i++)
316             assertEquals(42, (int) a[i]);
317     }
318 
319     /**
320      * toArray throws an ArrayStoreException when the given array can
321      * not store the objects inside the set
322      */
testToArray_ArrayStoreException()323     public void testToArray_ArrayStoreException() {
324         try {
325             CopyOnWriteArraySet c = new CopyOnWriteArraySet();
326             c.add("zfasdfsdf");
327             c.add("asdadasd");
328             c.toArray(new Long[5]);
329             shouldThrow();
330         } catch (ArrayStoreException success) {}
331     }
332 
333     /**
334      * A deserialized serialized set is equal
335      */
testSerialization()336     public void testSerialization() throws Exception {
337         Set x = populatedSet(SIZE);
338         Set y = serialClone(x);
339 
340         assertNotSame(y, x);
341         assertEquals(x.size(), y.size());
342         assertEquals(x.toString(), y.toString());
343         assertTrue(Arrays.equals(x.toArray(), y.toArray()));
344         assertEquals(x, y);
345         assertEquals(y, x);
346     }
347 
348     /**
349      * addAll is idempotent
350      */
testAddAll_idempotent()351     public void testAddAll_idempotent() throws Exception {
352         Set x = populatedSet(SIZE);
353         Set y = new CopyOnWriteArraySet(x);
354         y.addAll(x);
355         assertEquals(x, y);
356         assertEquals(y, x);
357     }
358 
359 }
360