001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tctest;
006:
007: import com.tc.object.config.ConfigVisitor;
008: import com.tc.object.config.DSOClientConfigHelper;
009: import com.tc.object.util.ReadOnlyException;
010: import com.tc.simulator.app.ApplicationConfig;
011: import com.tc.simulator.listener.ListenerProvider;
012: import com.tc.util.Assert;
013:
014: import gnu.trove.THashSet;
015:
016: import java.util.ArrayList;
017: import java.util.Arrays;
018: import java.util.Comparator;
019: import java.util.HashSet;
020: import java.util.Iterator;
021: import java.util.LinkedHashSet;
022: import java.util.List;
023: import java.util.Set;
024: import java.util.TreeSet;
025:
026: public class GenericSetTestApp extends GenericTestApp {
027:
028: private static final int LITERAL_VARIANT = 1;
029: private static final int OBJECT_VARIANT = 2;
030:
031: public GenericSetTestApp(String appId, ApplicationConfig cfg,
032: ListenerProvider listenerProvider) {
033: super (appId, cfg, listenerProvider, Set.class, 2);
034: }
035:
036: protected Object getTestObject(String testName) {
037: List sets = (List) sharedMap.get("sets");
038: return sets.iterator();
039: }
040:
041: protected void setupTestObject(String testName) {
042: List sets = new ArrayList();
043: sets.add(new HashSet());
044: sets.add(new LinkedHashSet());
045: sets.add(new THashSet());
046: sets.add(new TreeSet(new NullTolerantComparator()));
047: sets.add(new MyHashSet());
048: sets.add(new MyLinkedHashSet());
049: sets.add(new MyTHashSet());
050: sets.add(new MyTreeSet(new NullTolerantComparator()));
051: // sets.add(new SubclassOfAbstractLogicalSubclass());
052:
053: sharedMap.put("sets", sets);
054: sharedMap.put("arrayforHashSet", new Object[2]);
055: sharedMap.put("arrayforTHashSet", new Object[2]);
056: sharedMap.put("arrayforTreeSet", new Object[2]);
057: sharedMap.put("arrayforLinkedHashSet", new Object[2]);
058: sharedMap.put("arrayforMyHashSet", new Object[2]);
059: sharedMap.put("arrayforMyTHashSet", new Object[2]);
060: sharedMap.put("arrayforMyTreeSet", new Object[2]);
061: sharedMap.put("arrayforMyLinkedHashSet", new Object[2]);
062: }
063:
064: // This method is kind of like a macro, it returns an element (E == element) to be used
065: // in the set based on the variant value
066: Object E(String val, int variant) {
067: switch (variant) {
068: case LITERAL_VARIANT: {
069: return val;
070: }
071: case OBJECT_VARIANT: {
072: return new Foo(val);
073: }
074: default: {
075: throw new AssertionError("unknown variant: " + variant);
076: }
077: }
078:
079: // unreachable
080: }
081:
082: // Generic Set interface testing methods.
083: void testBasicAdd(Set set, boolean validate, int v) {
084: if (validate) {
085: assertSetsEqual(Arrays.asList(new Object[] {
086: E("January", v), E("February", v) }), set);
087: } else {
088: synchronized (set) {
089: boolean added = set.add(E("January", v));
090: Assert.assertTrue(added);
091: added = set.add(E("February", v));
092: Assert.assertTrue(added);
093: }
094: }
095: }
096:
097: void testAddAll(Set set, boolean validate, int v) {
098: if (validate) {
099: assertSetsEqual(Arrays.asList(new Object[] {
100: E("January", v), E("February", v) }), set);
101: } else {
102: Set toAdd = new LinkedHashSet();
103: toAdd.add(E("January", v));
104: toAdd.add(E("February", v));
105: synchronized (set) {
106: boolean added = set.addAll(toAdd);
107: Assert.assertTrue(added);
108: }
109: }
110: }
111:
112: void testClear(Set set, boolean validate, int v) {
113: if (validate) {
114: assertEmptySet(set);
115: } else {
116: Set toAdd = new HashSet();
117: toAdd.add(E("first element", v));
118: toAdd.add(E("second element", v));
119: synchronized (set) {
120: set.clear();
121: }
122: }
123: }
124:
125: void testAddNull(Set set, boolean validate, int v) {
126: if (validate) {
127: assertSetsEqual(Arrays.asList(new Object[] { null }), set);
128: } else {
129: System.err.println(set.getClass());
130: synchronized (set) {
131: boolean added = set.add(null);
132: if (!added)
133: throw new AssertionError("not added!");
134: }
135: }
136: }
137:
138: void testElementRetention(Set set, boolean validate, int v) {
139: if (v == LITERAL_VARIANT)
140: return;
141:
142: if (validate) {
143: Foo f = (Foo) set.iterator().next();
144: Assert.assertEquals(set.getClass().getName(), "id1", f.id);
145: } else {
146: Foo f1 = (Foo) E("1", v);
147: f1.id = "id1";
148: Foo f2 = (Foo) E("1", v);
149: f2.id = "id2";
150:
151: synchronized (set) {
152: boolean added = set.add(f1);
153: if (!added)
154: throw new AssertionError("not added!");
155: }
156:
157: synchronized (set) {
158: boolean added = set.add(f2);
159: if (added)
160: throw new AssertionError("added!");
161: }
162: }
163: }
164:
165: void testRemove(Set set, boolean validate, int v) {
166: if (validate) {
167: assertSetsEqual(Arrays.asList(new Object[] {
168: E("January", v), E("March", v) }), set);
169: } else {
170: synchronized (set) {
171: set.add(E("January", v));
172: set.add(E("February", v));
173: set.add(E("March", v));
174: }
175: synchronized (set) {
176: boolean remove = set.remove(E("February", v));
177: if (!remove)
178: throw new AssertionError("not removed");
179: }
180: }
181: }
182:
183: void testRemoveAll(Set set, boolean validate, int v) {
184: if (validate) {
185: assertSetsEqual(Arrays.asList(new Object[] {
186: E("January", v), E("April", v) }), set);
187: } else {
188: synchronized (set) {
189: set.add(E("January", v));
190: set.add(E("February", v));
191: set.add(E("March", v));
192: set.add(E("April", v));
193: }
194: Set toRemove = new HashSet();
195: toRemove.add(E("February", v));
196: toRemove.add(E("March", v));
197: synchronized (set) {
198: set.removeAll(toRemove);
199: }
200: }
201: }
202:
203: void testRetainAll(Set set, boolean validate, int v) {
204: if (validate) {
205: assertSetsEqual(Arrays.asList(new Object[] {
206: E("February", v), E("March", v) }), set);
207: } else {
208: synchronized (set) {
209: set.add(E("January", v));
210: set.add(E("February", v));
211: set.add(E("March", v));
212: set.add(E("April", v));
213: }
214: Set toRetain = new HashSet();
215: toRetain.add(E("February", v));
216: toRetain.add(E("March", v));
217: synchronized (set) {
218: set.retainAll(toRetain);
219: }
220: }
221: }
222:
223: void testToArray(Set set, boolean validate, int v) {
224: Object[] array = getArray(set);
225:
226: if (validate) {
227: assertSetsEqual(Arrays.asList(array), set);
228: } else {
229: synchronized (set) {
230: set.add(E("January", v));
231: set.add(E("February", v));
232: }
233: synchronized (array) {
234: Object[] returnArray = set.toArray(array);
235: Assert.assertTrue(returnArray == array);
236: }
237: }
238: }
239:
240: void testToArray2(Set set, boolean validate, int v) {
241: Object[] array = getArray(set);
242:
243: if (validate) {
244: Assert.assertEquals(set.getClass(), E("January", v),
245: array[0]);
246: Assert.assertEquals(set.getClass(), null, array[1]);
247: } else {
248: synchronized (set) {
249: set.add(E("January", v));
250: }
251:
252: // ensure that the array is bigger than the set size
253: // This test case makes sure the array get's null terminated
254: Assert.assertEquals(1, set.size());
255: Assert.assertEquals(2, array.length);
256:
257: // make sure the array contains no nulls
258: synchronized (array) {
259: Arrays.fill(array, new Object());
260: }
261:
262: synchronized (array) {
263: Object[] returnArray = set.toArray(array);
264: Assert.assertTrue(returnArray == array);
265: }
266: }
267: }
268:
269: // Iterator interface testing methods.
270: void testIteratorRemove(Set set, boolean validate, int v) {
271: if (validate) {
272: assertSetsEqual(Arrays.asList(new Object[] {
273: E("January", v), E("February", v) }), set);
274: } else {
275: synchronized (set) {
276: set.add(E("January", v));
277: set.add(E("February", v));
278: set.add(E("March", v));
279: }
280:
281: synchronized (set) {
282: for (Iterator iterator = set.iterator(); iterator
283: .hasNext();) {
284: if (E("March", v).equals(iterator.next())) {
285: iterator.remove();
286: }
287: }
288: }
289: }
290: }
291:
292: void testIteratorRemoveNull(Set set, boolean validate, int v) {
293: if (validate) {
294: assertSetsEqual(Arrays.asList(new Object[] {
295: E("January", v), E("February", v) }), set);
296: } else {
297: synchronized (set) {
298: set.add(E("January", v));
299: set.add(null);
300: set.add(E("February", v));
301: }
302: synchronized (set) {
303: Iterator iterator = set.iterator();
304: Assert.assertEquals(true, iterator.hasNext());
305: while (iterator.hasNext()) {
306: Object o = iterator.next();
307: if (o == null) {
308: iterator.remove();
309: }
310: }
311: }
312: }
313: }
314:
315: // ReadOnly testing methods.
316: void testReadOnlyAdd(Set set, boolean validate, int v) {
317: if (validate) {
318: assertEmptySet(set);
319: } else {
320: synchronized (set) {
321: try {
322: set.add(E("first element", v));
323: throw new AssertionError(
324: "Should have thrown a ReadOnlyException");
325: } catch (ReadOnlyException e) {
326: // Excepted
327: }
328: }
329: }
330: }
331:
332: void testReadOnlyAddAll(Set set, boolean validate, int v) {
333: if (validate) {
334: assertEmptySet(set);
335: } else {
336: Set toAdd = new HashSet();
337: toAdd.add(E("first element", v));
338: toAdd.add(E("second element", v));
339: synchronized (set) {
340: try {
341: set.addAll(toAdd);
342: throw new AssertionError(
343: "Should have thrown a ReadOnlyException");
344: } catch (ReadOnlyException r) {
345: // Expected
346: }
347: }
348: }
349: }
350:
351: // Setting up for the ReadOnly test for remove.
352: void testSetUpRemove(Set set, boolean validate, int v) {
353: if (validate) {
354: assertSetsEqual(Arrays.asList(new Object[] {
355: E("January", v), E("February", v) }), set);
356: } else {
357: synchronized (set) {
358: set.add(E("January", v));
359: set.add(E("February", v));
360: }
361: tryReadOnlyRemove(set, v);
362: }
363: }
364:
365: // tryReadOnlyRemove() goes hand in hand with testSetUpRemove().
366: private void tryReadOnlyRemove(Set set, int v) {
367: synchronized (set) {
368: try {
369: set.remove(E("February", v));
370: throw new AssertionError(
371: "Should have thrown a ReadOnlyException");
372: } catch (ReadOnlyException t) {
373: // expected
374: }
375: }
376: }
377:
378: // Setting up for the ReadOnly test for iterator remove.
379: void testSetUpIteratorRemove(Set set, boolean validate, int v) {
380: if (validate) {
381: assertSetsEqual(Arrays.asList(new Object[] {
382: E("January", v), E("February", v) }), set);
383: } else {
384: synchronized (set) {
385: set.add(E("January", v));
386: set.add(E("February", v));
387: }
388: tryReadOnlyIteratorRemove(set);
389: }
390: }
391:
392: // tryReadOnlyIteratorRemove() goes hand in hand with testSetUpIteratorRemove().
393: private void tryReadOnlyIteratorRemove(Set set) {
394: synchronized (set) {
395: try {
396: Iterator iterator = set.iterator();
397: iterator.next();
398: iterator.remove();
399: throw new AssertionError(
400: "Should have thrown a ReadOnlyException");
401: } catch (ReadOnlyException r) {
402: // Read Only Exception is expected
403: }
404: }
405: }
406:
407: // Setting up for the ReadOnly test for clear.
408: void testSetUpClear(Set set, boolean validate, int v) {
409: if (validate) {
410: assertSetsEqual(Arrays.asList(new Object[] {
411: E("January", v), E("February", v) }), set);
412: } else {
413: synchronized (set) {
414: set.add(E("January", v));
415: set.add(E("February", v));
416: }
417: tryReadOnlyClear(set);
418: }
419: }
420:
421: // tryReadOnlyClear() goes hand in hand with testSetUpClear().
422: private void tryReadOnlyClear(Set set) {
423: synchronized (set) {
424: try {
425: set.clear();
426: throw new AssertionError(
427: "Should have thrown a ReadOnlyException");
428: } catch (ReadOnlyException t) {
429: // Excepted
430: }
431: }
432: }
433:
434: // Setting up for the ReadOnly test for toArray.
435: void testSetUpToArray(Set set, boolean validate, int v) {
436: if (validate) {
437: Object[] array = getArray(set);
438: assertEmptyObjectArray(array);
439: } else {
440: synchronized (set) {
441: set.add(E("January", v));
442: set.add(E("February", v));
443: }
444: tryReadOnlyToArray(set);
445: }
446: }
447:
448: // tryReadOnlyToArray() goes hand in hand with testSetUpToArray().
449: void tryReadOnlyToArray(Set set) {
450: Object[] array = getArray(set);
451: synchronized (array) {
452: try {
453: Object[] returnArray = set.toArray(array);
454: Assert.assertTrue(returnArray == array);
455: throw new AssertionError(
456: "Should have thrown a ReadOnlyException");
457: } catch (ReadOnlyException t) {
458: // Excepted
459: }
460: }
461: }
462:
463: // Setting up for the ReadOnly test for RetainAll.
464: void testSetUpRetainAll(Set set, boolean validate, int v) {
465: if (validate) {
466: assertSetsEqual(Arrays.asList(new Object[] {
467: E("January", v), E("February", v) }), set);
468: } else {
469: synchronized (set) {
470: set.add(E("January", v));
471: set.add(E("February", v));
472: }
473: tryReadOnlyRetainAll(set, v);
474: }
475: }
476:
477: // tryReadOnlyRetainAll() goes hand in hand with testSetUpRetainAll().
478: void tryReadOnlyRetainAll(Set set, int v) {
479: synchronized (set) {
480: Set toRetain = new HashSet();
481: toRetain.add(E("January", v));
482: try {
483: set.retainAll(toRetain);
484: throw new AssertionError(
485: "Should have thrown a ReadOnlyException");
486: } catch (ReadOnlyException t) {
487: // expected
488: }
489: }
490: }
491:
492: // Setting up for the ReadOnly test for RemoveAll.
493: void testSetUpRemoveAll(Set set, boolean validate, int v) {
494: if (validate) {
495: assertSetsEqual(Arrays.asList(new Object[] {
496: E("January", v), E("February", v) }), set);
497: } else {
498: synchronized (set) {
499: set.add(E("January", v));
500: set.add(E("February", v));
501: }
502: tryReadOnlyRemoveAll(set, v);
503: }
504: }
505:
506: // tryReadOnlyRemoveAll() goes hand in hand with testSetUpRemoveAll().
507: void tryReadOnlyRemoveAll(Set set, int v) {
508: synchronized (set) {
509: Set toRemove = new HashSet();
510: toRemove.add(E("January", v));
511: try {
512: set.removeAll(toRemove);
513: throw new AssertionError(
514: "Should have thrown a ReadOnlyException");
515: } catch (ReadOnlyException t) {
516: // Excepted
517: }
518: }
519: }
520:
521: private Object getMySubclassArray(Set set) {
522: if (set instanceof MyLinkedHashSet) {
523: return sharedMap.get("arrayforMyLinkedHashSet");
524: }
525: if (set instanceof MyHashSet) {
526: return sharedMap.get("arrayforMyHashSet");
527: }
528: if (set instanceof MyTHashSet) {
529: return sharedMap.get("arrayforMyTHashSet");
530: }
531: if (set instanceof MyTreeSet) {
532: return sharedMap.get("arrayforMyTreeSet");
533: }
534: return null;
535: }
536:
537: private Object[] getArray(Set set) {
538: Object o = getMySubclassArray(set);
539: if (o != null) {
540: return (Object[]) o;
541: }
542:
543: if (set instanceof LinkedHashSet) {
544: return (Object[]) sharedMap.get("arrayforLinkedHashSet");
545: }
546: if (set instanceof HashSet) {
547: return (Object[]) sharedMap.get("arrayforHashSet");
548: }
549: if (set instanceof THashSet) {
550: return (Object[]) sharedMap.get("arrayforTHashSet");
551: }
552: if (set instanceof TreeSet) {
553: return (Object[]) sharedMap.get("arrayforTreeSet");
554: }
555: return null;
556: }
557:
558: private static void assertEmptyObjectArray(Object[] array) {
559: for (int i = 0; i < array.length; i++) {
560: Assert.assertNull(array[i]);
561: }
562: }
563:
564: private static void assertEmptySet(Set set) {
565: Assert.assertEquals(0, set.size());
566: Assert.assertTrue(set.isEmpty());
567:
568: int count = 0;
569: for (Iterator i = set.iterator(); i.hasNext();) {
570: count++;
571: }
572: Assert.assertEquals(0, count);
573: }
574:
575: private static void assertSetsEqual(List expectElements, Set actual) {
576: String type = actual.getClass().getName();
577:
578: Assert.assertEquals(type, expectElements.size(), actual.size());
579:
580: if (actual instanceof LinkedHashSet) {
581: for (Iterator iExpect = expectElements.iterator(), iActual = actual
582: .iterator(); iExpect.hasNext();) {
583: Assert.assertEquals(type, iExpect.next(), iActual
584: .next());
585: }
586: }
587:
588: Assert.assertTrue(type, expectElements.containsAll(actual));
589: Assert.assertTrue(type, actual.containsAll(expectElements));
590:
591: if (expectElements.isEmpty()) {
592: Assert.assertTrue(type, actual.isEmpty());
593: } else {
594: Assert.assertFalse(type, actual.isEmpty());
595: }
596: }
597:
598: public static void visitL1DSOConfig(ConfigVisitor visitor,
599: DSOClientConfigHelper config) {
600: config.getOrCreateSpec(NullTolerantComparator.class.getName());
601: String testClass = GenericSetTestApp.class.getName();
602: config.addIncludePattern(testClass + "$*");
603: config.getOrCreateSpec(testClass);
604: String writeAllowedMethodExpression = "* " + testClass
605: + "*.*(..)";
606: config.addWriteAutolock(writeAllowedMethodExpression);
607: String readOnlyMethodExpression = "* " + testClass
608: + "*.*ReadOnly*(..)";
609: config.addReadAutolock(readOnlyMethodExpression);
610: }
611:
612: private static class MyHashSet extends HashSet {
613: public MyHashSet() {
614: super ();
615: }
616: }
617:
618: private static class MyLinkedHashSet extends LinkedHashSet {
619: public MyLinkedHashSet() {
620: super ();
621: }
622: }
623:
624: private static class MyTHashSet extends THashSet {
625: public MyTHashSet() {
626: super ();
627: }
628: }
629:
630: private static class MyTreeSet extends TreeSet {
631: public MyTreeSet(Comparator comparator) {
632: super (comparator);
633: }
634: }
635:
636: private static class Foo implements Comparable {
637: private final String value;
638:
639: // This field isn't used in equals/hashCode -- It is only here to test which instance is retained when
640: // two unique (but equal) objects are added to a set
641: private String id;
642:
643: Foo(String value) {
644: this .value = value;
645: }
646:
647: public int hashCode() {
648: return value.hashCode();
649: }
650:
651: public boolean equals(Object obj) {
652: if (obj instanceof Foo) {
653: return value.equals(((Foo) obj).value);
654: }
655: return false;
656: }
657:
658: public int compareTo(Object o) {
659: return value.compareTo(((Foo) o).value);
660: }
661: }
662:
663: }
|