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 with assistance from members of JCP JSR-166 30 * Expert Group and released to the public domain, as explained at 31 * http://creativecommons.org/publicdomain/zero/1.0/ 32 * Other contributors include Andrew Wright, Jeffrey Hayes, 33 * Pat Fisher, Mike Judd. 34 */ 35 36 import java.util.ArrayList; 37 import java.util.Arrays; 38 import java.util.Collection; 39 import java.util.Iterator; 40 import java.util.NoSuchElementException; 41 import java.util.Set; 42 import java.util.concurrent.CopyOnWriteArraySet; 43 44 import junit.framework.Test; 45 46 public class CopyOnWriteArraySetTest extends JSR166TestCase { main(String[] args)47 public static void main(String[] args) { 48 main(suite(), args); 49 } suite()50 public static Test suite() { 51 class Implementation implements CollectionImplementation { 52 public Class<?> klazz() { return CopyOnWriteArraySet.class; } 53 public Set emptyCollection() { return new CopyOnWriteArraySet(); } 54 public Object makeElement(int i) { return JSR166TestCase.itemFor(i); } 55 public boolean isConcurrent() { return true; } 56 public boolean permitsNulls() { return true; } 57 } 58 return newTestSuite( 59 CopyOnWriteArraySetTest.class, 60 CollectionTest.testSuite(new Implementation())); 61 } 62 populatedSet(int n)63 static CopyOnWriteArraySet<Item> populatedSet(int n) { 64 CopyOnWriteArraySet<Item> a = new CopyOnWriteArraySet<>(); 65 assertTrue(a.isEmpty()); 66 for (int i = 0; i < n; i++) 67 mustAdd(a, i); 68 mustEqual(n == 0, a.isEmpty()); 69 mustEqual(n, a.size()); 70 return a; 71 } 72 populatedSet(Item[] elements)73 static CopyOnWriteArraySet<Item> populatedSet(Item[] elements) { 74 CopyOnWriteArraySet<Item> a = new CopyOnWriteArraySet<>(); 75 assertTrue(a.isEmpty()); 76 for (int i = 0; i < elements.length; i++) 77 mustAdd(a, elements[i]); 78 assertFalse(a.isEmpty()); 79 mustEqual(elements.length, a.size()); 80 return a; 81 } 82 83 /** 84 * Default-constructed set is empty 85 */ testConstructor()86 public void testConstructor() { 87 CopyOnWriteArraySet<Item> a = new CopyOnWriteArraySet<>(); 88 assertTrue(a.isEmpty()); 89 } 90 91 /** 92 * Collection-constructed set holds all of its elements 93 */ testConstructor3()94 public void testConstructor3() { 95 Item[] items = defaultItems; 96 CopyOnWriteArraySet<Item> a = new CopyOnWriteArraySet<>(Arrays.asList(items)); 97 for (int i = 0; i < SIZE; ++i) 98 mustContain(a, i); 99 } 100 101 /** 102 * addAll adds each non-duplicate element from the given collection 103 */ testAddAll()104 public void testAddAll() { 105 Set<Item> full = populatedSet(3); 106 assertTrue(full.addAll(Arrays.asList(three, four, five))); 107 mustEqual(6, full.size()); 108 assertFalse(full.addAll(Arrays.asList(three, four, five))); 109 mustEqual(6, full.size()); 110 } 111 112 /** 113 * addAll adds each non-duplicate element from the given collection 114 */ testAddAll2()115 public void testAddAll2() { 116 Set<Item> full = populatedSet(3); 117 // "one" is duplicate and will not be added 118 assertTrue(full.addAll(Arrays.asList(three, four, one))); 119 mustEqual(5, full.size()); 120 assertFalse(full.addAll(Arrays.asList(three, four, one))); 121 mustEqual(5, full.size()); 122 } 123 124 /** 125 * add will not add the element if it already exists in the set 126 */ testAdd2()127 public void testAdd2() { 128 Set<Item> full = populatedSet(3); 129 full.add(one); 130 mustEqual(3, full.size()); 131 } 132 133 /** 134 * add adds the element when it does not exist in the set 135 */ testAdd3()136 public void testAdd3() { 137 Set<Item> full = populatedSet(3); 138 full.add(three); 139 mustContain(full, three); 140 } 141 142 /** 143 * clear removes all elements from the set 144 */ testClear()145 public void testClear() { 146 Collection<Item> full = populatedSet(3); 147 full.clear(); 148 mustEqual(0, full.size()); 149 assertTrue(full.isEmpty()); 150 } 151 152 /** 153 * contains returns true for added elements 154 */ testContains()155 public void testContains() { 156 Collection<Item> full = populatedSet(3); 157 mustContain(full, one); 158 mustNotContain(full, five); 159 } 160 161 /** 162 * Sets with equal elements are equal 163 */ testEquals()164 public void testEquals() { 165 CopyOnWriteArraySet<Item> a = populatedSet(3); 166 CopyOnWriteArraySet<Item> b = populatedSet(3); 167 assertTrue(a.equals(b)); 168 assertTrue(b.equals(a)); 169 assertTrue(a.containsAll(b)); 170 assertTrue(b.containsAll(a)); 171 mustEqual(a.hashCode(), b.hashCode()); 172 mustEqual(a.size(), b.size()); 173 174 a.add(minusOne); 175 assertFalse(a.equals(b)); 176 assertFalse(b.equals(a)); 177 assertTrue(a.containsAll(b)); 178 assertFalse(b.containsAll(a)); 179 b.add(minusOne); 180 assertTrue(a.equals(b)); 181 assertTrue(b.equals(a)); 182 assertTrue(a.containsAll(b)); 183 assertTrue(b.containsAll(a)); 184 mustEqual(a.hashCode(), b.hashCode()); 185 186 Item x = a.iterator().next(); 187 a.remove(x); 188 assertFalse(a.equals(b)); 189 assertFalse(b.equals(a)); 190 assertFalse(a.containsAll(b)); 191 assertTrue(b.containsAll(a)); 192 a.add(x); 193 assertTrue(a.equals(b)); 194 assertTrue(b.equals(a)); 195 assertTrue(a.containsAll(b)); 196 assertTrue(b.containsAll(a)); 197 mustEqual(a.hashCode(), b.hashCode()); 198 mustEqual(a.size(), b.size()); 199 200 CopyOnWriteArraySet<Item> empty1 = new CopyOnWriteArraySet<>(Arrays.asList()); 201 CopyOnWriteArraySet<Item> empty2 = new CopyOnWriteArraySet<>(Arrays.asList()); 202 assertTrue(empty1.equals(empty1)); 203 assertTrue(empty1.equals(empty2)); 204 205 assertFalse(empty1.equals(a)); 206 assertFalse(a.equals(empty1)); 207 208 assertFalse(a.equals(null)); 209 } 210 211 /** 212 * containsAll returns true for collections with subset of elements 213 */ testContainsAll()214 public void testContainsAll() { 215 Collection<Item> full = populatedSet(3); 216 assertTrue(full.containsAll(full)); 217 assertTrue(full.containsAll(Arrays.asList())); 218 assertTrue(full.containsAll(Arrays.asList(one))); 219 assertTrue(full.containsAll(Arrays.asList(one, two))); 220 assertFalse(full.containsAll(Arrays.asList(one, two, six))); 221 assertFalse(full.containsAll(Arrays.asList(six))); 222 223 CopyOnWriteArraySet<Item> empty1 = new CopyOnWriteArraySet<>(Arrays.asList()); 224 CopyOnWriteArraySet<Item> empty2 = new CopyOnWriteArraySet<>(Arrays.asList()); 225 assertTrue(empty1.containsAll(empty2)); 226 assertTrue(empty1.containsAll(empty1)); 227 assertFalse(empty1.containsAll(full)); 228 assertTrue(full.containsAll(empty1)); 229 230 try { 231 full.containsAll(null); 232 shouldThrow(); 233 } catch (NullPointerException success) {} 234 } 235 236 /** 237 * isEmpty is true when empty, else false 238 */ testIsEmpty()239 public void testIsEmpty() { 240 assertTrue(populatedSet(0).isEmpty()); 241 assertFalse(populatedSet(3).isEmpty()); 242 } 243 244 /** 245 * iterator() returns an iterator containing the elements of the 246 * set in insertion order 247 */ testIterator()248 public void testIterator() { 249 Collection<Item> empty = new CopyOnWriteArraySet<>(); 250 assertFalse(empty.iterator().hasNext()); 251 try { 252 empty.iterator().next(); 253 shouldThrow(); 254 } catch (NoSuchElementException success) {} 255 256 Item[] elements = seqItems(SIZE); 257 shuffle(elements); 258 Collection<Item> full = populatedSet(elements); 259 260 Iterator<? extends Item> it = full.iterator(); 261 for (int j = 0; j < SIZE; j++) { 262 assertTrue(it.hasNext()); 263 mustEqual(elements[j], it.next()); 264 } 265 assertIteratorExhausted(it); 266 } 267 268 /** 269 * iterator of empty collection has no elements 270 */ testEmptyIterator()271 public void testEmptyIterator() { 272 assertIteratorExhausted(new CopyOnWriteArraySet<Item>().iterator()); 273 } 274 275 /** 276 * iterator remove is unsupported 277 */ testIteratorRemove()278 public void testIteratorRemove() { 279 Collection<Item> full = populatedSet(3); 280 Iterator<? extends Item> it = full.iterator(); 281 it.next(); 282 try { 283 it.remove(); 284 shouldThrow(); 285 } catch (UnsupportedOperationException success) {} 286 } 287 288 /** 289 * toString holds toString of elements 290 */ testToString()291 public void testToString() { 292 mustEqual("[]", new CopyOnWriteArraySet<Item>().toString()); 293 Collection<Item> full = populatedSet(3); 294 String s = full.toString(); 295 for (int i = 0; i < 3; ++i) 296 assertTrue(s.contains(String.valueOf(i))); 297 mustEqual(new ArrayList<Item>(full).toString(), 298 full.toString()); 299 } 300 301 /** 302 * removeAll removes all elements from the given collection 303 */ testRemoveAll()304 public void testRemoveAll() { 305 Set<Item> full = populatedSet(3); 306 assertTrue(full.removeAll(Arrays.asList(one, two))); 307 mustEqual(1, full.size()); 308 assertFalse(full.removeAll(Arrays.asList(one, two))); 309 mustEqual(1, full.size()); 310 } 311 312 /** 313 * remove removes an element 314 */ testRemove()315 public void testRemove() { 316 Collection<Item> full = populatedSet(3); 317 full.remove(one); 318 mustNotContain(full, one); 319 mustEqual(2, full.size()); 320 } 321 322 /** 323 * size returns the number of elements 324 */ testSize()325 public void testSize() { 326 Collection<Item> empty = new CopyOnWriteArraySet<>(); 327 Collection<Item> full = populatedSet(3); 328 mustEqual(3, full.size()); 329 mustEqual(0, empty.size()); 330 } 331 332 /** 333 * toArray() returns an Object array containing all elements from 334 * the set in insertion order 335 */ testToArray()336 public void testToArray() { 337 Object[] a = new CopyOnWriteArraySet<>().toArray(); 338 assertTrue(Arrays.equals(new Object[0], a)); 339 assertSame(Object[].class, a.getClass()); 340 341 Item[] elements = seqItems(SIZE); 342 shuffle(elements); 343 Collection<Item> full = populatedSet(elements); 344 345 assertTrue(Arrays.equals(elements, full.toArray())); 346 assertSame(Object[].class, full.toArray().getClass()); 347 } 348 349 /** 350 * toArray(Item array) returns an Item array containing all 351 * elements from the set in insertion order 352 */ testToArray2()353 public void testToArray2() { 354 Collection<Item> empty = new CopyOnWriteArraySet<>(); 355 Item[] a; 356 357 a = new Item[0]; 358 assertSame(a, empty.toArray(a)); 359 360 a = new Item[SIZE / 2]; 361 Arrays.fill(a, fortytwo); 362 assertSame(a, empty.toArray(a)); 363 assertNull(a[0]); 364 for (int i = 1; i < a.length; i++) 365 mustEqual(42, a[i]); 366 367 Item[] elements = seqItems(SIZE); 368 shuffle(elements); 369 Collection<Item> full = populatedSet(elements); 370 371 Arrays.fill(a, fortytwo); 372 assertTrue(Arrays.equals(elements, full.toArray(a))); 373 for (int i = 0; i < a.length; i++) 374 mustEqual(42, a[i]); 375 assertSame(Item[].class, full.toArray(a).getClass()); 376 377 a = new Item[SIZE]; 378 Arrays.fill(a, fortytwo); 379 assertSame(a, full.toArray(a)); 380 assertTrue(Arrays.equals(elements, a)); 381 382 a = new Item[2 * SIZE]; 383 Arrays.fill(a, fortytwo); 384 assertSame(a, full.toArray(a)); 385 assertTrue(Arrays.equals(elements, Arrays.copyOf(a, SIZE))); 386 assertNull(a[SIZE]); 387 for (int i = SIZE + 1; i < a.length; i++) 388 mustEqual(42, a[i]); 389 } 390 391 /** 392 * toArray throws an ArrayStoreException when the given array can 393 * not store the objects inside the set 394 */ 395 @SuppressWarnings("CollectionToArraySafeParameter") testToArray_ArrayStoreException()396 public void testToArray_ArrayStoreException() { 397 CopyOnWriteArraySet<Item> c = new CopyOnWriteArraySet<>(); 398 c.add(one); 399 c.add(two); 400 try { 401 c.toArray(new Long[5]); 402 shouldThrow(); 403 } catch (ArrayStoreException success) {} 404 } 405 406 /** 407 * A deserialized/reserialized set equals original 408 */ testSerialization()409 public void testSerialization() throws Exception { 410 Set<Item> x = populatedSet(SIZE); 411 Set<Item> y = serialClone(x); 412 413 assertNotSame(y, x); 414 mustEqual(x.size(), y.size()); 415 mustEqual(x.toString(), y.toString()); 416 assertTrue(Arrays.equals(x.toArray(), y.toArray())); 417 mustEqual(x, y); 418 mustEqual(y, x); 419 } 420 421 /** 422 * addAll is idempotent 423 */ testAddAll_idempotent()424 public void testAddAll_idempotent() throws Exception { 425 Set<Item> x = populatedSet(SIZE); 426 Set<Item> y = new CopyOnWriteArraySet<>(x); 427 y.addAll(x); 428 mustEqual(x, y); 429 mustEqual(y, x); 430 } 431 432 } 433