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