001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tctest;
005:
006: import com.tc.exception.TCRuntimeException;
007: import com.tc.object.config.ConfigVisitor;
008: import com.tc.object.config.DSOClientConfigHelper;
009: import com.tc.object.config.TransparencyClassSpec;
010: import com.tc.object.util.ReadOnlyException;
011: import com.tc.simulator.app.ApplicationConfig;
012: import com.tc.simulator.listener.ListenerProvider;
013: import com.tc.util.Assert;
014:
015: import java.util.ArrayList;
016: import java.util.Arrays;
017: import java.util.Collection;
018: import java.util.Iterator;
019: import java.util.List;
020: import java.util.concurrent.CyclicBarrier;
021: import java.util.concurrent.LinkedBlockingQueue;
022: import java.util.concurrent.TimeUnit;
023:
024: public class GenericQueueTestApp extends GenericTestApp {
025: private final CyclicBarrier localBarrier = new CyclicBarrier(2);
026:
027: public GenericQueueTestApp(String appId, ApplicationConfig cfg,
028: ListenerProvider listenerProvider) {
029: super (appId, cfg, listenerProvider, LinkedBlockingQueue.class);
030: }
031:
032: protected Object getTestObject(String testName) {
033: List lists = (List) sharedMap.get("queues");
034: return lists.iterator();
035: }
036:
037: protected void setupTestObject(String testName) {
038: List lists = new ArrayList();
039: lists.add(new LinkedBlockingQueue());
040: lists.add(new LinkedBlockingQueue(5));
041:
042: sharedMap.put("queues", lists);
043: sharedMap.put("arrayForBlockingQueue", new Object[4]);
044: sharedMap.put("arrayForBlockingQueue2", new Object[4]);
045: sharedMap.put("collectionForBlockingQueue", new ArrayList());
046: sharedMap.put("collectionForBlockingQueue2", new ArrayList());
047: }
048:
049: void testBasicAdd(LinkedBlockingQueue queue, boolean validate) {
050: if (validate) {
051: assertQueueEqual(Arrays.asList(new Object[] {
052: "First element", "Second element" }), queue);
053: } else {
054: queue.add("First element");
055: queue.add("Second element");
056: }
057: }
058:
059: void testAddAll(LinkedBlockingQueue queue, boolean validate) {
060: List toAdd = new ArrayList();
061: toAdd.add("First element");
062: toAdd.add("Second element");
063: if (validate) {
064: assertQueueEqual(toAdd, queue);
065: } else {
066: queue.addAll(toAdd);
067: }
068: }
069:
070: void testElement(LinkedBlockingQueue queue, boolean validate) {
071: List toAdd = new ArrayList();
072: toAdd.add("First element");
073: toAdd.add("Second element");
074: if (validate) {
075: Assert.assertEquals(toAdd.get(0), queue.element());
076: } else {
077: queue.addAll(toAdd);
078: }
079: }
080:
081: void testContains(LinkedBlockingQueue queue, boolean validate) {
082: List toAdd = new ArrayList();
083: toAdd.add("First element");
084: toAdd.add("Second element");
085: if (validate) {
086: queue.contains(toAdd.get(1));
087: } else {
088: queue.addAll(toAdd);
089: }
090: }
091:
092: void testContainsAll(LinkedBlockingQueue queue, boolean validate) {
093: List toAdd = new ArrayList();
094: toAdd.add("First element");
095: toAdd.add("Second element");
096: if (validate) {
097: Assert.assertFalse(queue.isEmpty());
098: queue.containsAll(toAdd);
099: } else {
100: Assert.assertTrue(queue.isEmpty());
101: queue.addAll(toAdd);
102: Assert.assertFalse(queue.isEmpty());
103: }
104: }
105:
106: void testBasicPut(LinkedBlockingQueue queue, boolean validate) {
107: if (validate) {
108: assertSingleElement("First element", queue);
109: } else {
110: try {
111: queue.put("First element");
112: } catch (InterruptedException e) {
113: throw new TCRuntimeException(e);
114: }
115: }
116: }
117:
118: void testPut(LinkedBlockingQueue queue, boolean validate) {
119: if (validate) {
120: assertQueueEqual(Arrays.asList(new Object[] {
121: "First element", "Second element" }), queue);
122: } else {
123: try {
124: queue.put("First element");
125: queue.put("Second element");
126: } catch (InterruptedException e) {
127: throw new TCRuntimeException(e);
128: }
129: }
130: }
131:
132: void testClear(LinkedBlockingQueue queue, boolean validate) {
133: if (validate) {
134: assertEmptyQueue(queue);
135: } else {
136: try {
137: queue.put("First element");
138: queue.put("Second element");
139: } catch (InterruptedException e) {
140: throw new TCRuntimeException(e);
141: }
142: queue.clear();
143: }
144: }
145:
146: void testDrainTo1(LinkedBlockingQueue queue, boolean validate) {
147: if (validate) {
148: assertEmptyQueue(queue);
149: } else {
150: try {
151: queue.put("First element");
152: queue.put("Second element");
153: } catch (InterruptedException e) {
154: throw new TCRuntimeException(e);
155: }
156: List list = new ArrayList();
157: queue.drainTo(list);
158: assertCollectionEqual(Arrays.asList(new Object[] {
159: "First element", "Second element" }), list);
160: }
161: }
162:
163: void testDrainToWithSharedCollection1(LinkedBlockingQueue queue,
164: boolean validate) {
165: Collection collection = getCollection(queue);
166: if (validate) {
167: assertEmptyQueue(queue);
168: assertCollectionEqual(Arrays.asList(new Object[] {
169: "First element", "Second element" }), collection);
170: } else {
171: try {
172: queue.put("First element");
173: queue.put("Second element");
174: } catch (InterruptedException e) {
175: throw new TCRuntimeException(e);
176: }
177: synchronized (collection) {
178: queue.drainTo(collection);
179: }
180: }
181: }
182:
183: void testDrainTo2(LinkedBlockingQueue queue, boolean validate) {
184: if (validate) {
185: assertQueueEqual(Arrays.asList(new Object[] {
186: "Third element", "Fourth element" }), queue);
187: } else {
188: try {
189: queue.put("First element");
190: queue.put("Second element");
191: queue.put("Third element");
192: queue.put("Fourth element");
193: } catch (InterruptedException e) {
194: throw new TCRuntimeException(e);
195: }
196: List list = new ArrayList();
197: queue.drainTo(list, 2);
198: assertCollectionEqual(Arrays.asList(new Object[] {
199: "First element", "Second element" }), list);
200: }
201: }
202:
203: void testDrainToWithSharedCollection2(LinkedBlockingQueue queue,
204: boolean validate) {
205: Collection collection = getCollection(queue);
206: if (validate) {
207: assertQueueEqual(Arrays.asList(new Object[] {
208: "Third element", "Fourth element" }), queue);
209: assertCollectionEqual(Arrays.asList(new Object[] {
210: "First element", "Second element" }), collection);
211: } else {
212: try {
213: queue.put("First element");
214: queue.put("Second element");
215: queue.put("Third element");
216: queue.put("Fourth element");
217: } catch (InterruptedException e) {
218: throw new TCRuntimeException(e);
219: }
220: synchronized (collection) {
221: queue.drainTo(collection, 2);
222: }
223: }
224: }
225:
226: void testOffer(LinkedBlockingQueue queue, boolean validate) {
227: if (validate) {
228: assertQueueEqual(Arrays.asList(new Object[] {
229: "First element", "Second element", "Third element",
230: "Fourth element", "Fifth element" }), queue);
231: } else {
232: try {
233: queue.put("First element");
234: queue.put("Second element");
235: queue.put("Third element");
236: queue.put("Fourth element");
237: } catch (InterruptedException e) {
238: throw new TCRuntimeException(e);
239: }
240:
241: queue.offer("Fifth element");
242: }
243: }
244:
245: void testOfferFull(LinkedBlockingQueue queue, boolean validate) {
246: if (validate) {
247: assertQueueEqual(Arrays.asList(new Object[] {
248: "First element", "Second element", "Third element",
249: "Fourth element", "Fifth element" }), queue);
250: } else {
251: try {
252: queue.put("First element");
253: queue.put("Second element");
254: queue.put("Third element");
255: queue.put("Fourth element");
256: queue.put("Fifth element");
257: } catch (InterruptedException e) {
258: throw new TCRuntimeException(e);
259: }
260:
261: if (queue.remainingCapacity() == 0) {
262: queue.offer("Sixth element");
263: }
264: }
265: }
266:
267: void testOfferTimeout1(LinkedBlockingQueue queue, boolean validate) {
268: if (validate) {
269: assertQueueEqual(Arrays.asList(new Object[] {
270: "First element", "Second element", "Third element",
271: "Fourth element", "Fifth element" }), queue);
272: } else {
273: try {
274: queue.put("First element");
275: queue.put("Second element");
276: queue.put("Third element");
277: queue.put("Fourth element");
278: queue.put("Fifth element");
279: } catch (InterruptedException e) {
280: throw new TCRuntimeException(e);
281: }
282:
283: if (queue.remainingCapacity() == 0) {
284: try {
285: queue.offer("Sixth element", 10,
286: TimeUnit.MILLISECONDS);
287: } catch (InterruptedException e) {
288: throw new TCRuntimeException(e);
289: }
290: }
291: }
292: }
293:
294: void testOfferTimeout2(LinkedBlockingQueue queue, boolean validate) {
295: if (validate) {
296: assertQueueEqual(Arrays
297: .asList(new Object[] { "Second element",
298: "Third element", "Fourth element",
299: "Fifth element", "Sixth element" }), queue);
300: } else {
301: try {
302: queue.put("First element");
303: queue.put("Second element");
304: queue.put("Third element");
305: queue.put("Fourth element");
306: queue.put("Fifth element");
307: } catch (InterruptedException e) {
308: throw new TCRuntimeException(e);
309: }
310:
311: Thread thread = new Thread(new QueueReader(queue,
312: localBarrier));
313: thread.start();
314: try {
315: queue.offer("Sixth element", 100, TimeUnit.SECONDS);
316: localBarrier.await();
317: } catch (Exception e) {
318: throw new TCRuntimeException(e);
319: }
320: }
321: }
322:
323: void testPeek(LinkedBlockingQueue queue, boolean validate) {
324: if (validate) {
325: assertQueueEqual(Arrays.asList(new Object[] {
326: "First element", "Second element", "Third element",
327: "Fourth element", "Fifth element" }), queue);
328: } else {
329: try {
330: queue.put("First element");
331: queue.put("Second element");
332: queue.put("Third element");
333: queue.put("Fourth element");
334: queue.put("Fifth element");
335: } catch (InterruptedException e) {
336: throw new TCRuntimeException(e);
337: }
338:
339: Assert.assertEquals("First element", queue.peek());
340: }
341: }
342:
343: void testPoll(LinkedBlockingQueue queue, boolean validate) {
344: if (validate) {
345: assertQueueEqual(Arrays.asList(new Object[] {
346: "Second element", "Third element",
347: "Fourth element", "Fifth element" }), queue);
348: } else {
349: try {
350: queue.put("First element");
351: queue.put("Second element");
352: queue.put("Third element");
353: queue.put("Fourth element");
354: queue.put("Fifth element");
355: } catch (InterruptedException e) {
356: throw new TCRuntimeException(e);
357: }
358:
359: Assert.assertEquals("First element", queue.poll());
360: }
361: }
362:
363: void testPollTimeout1(LinkedBlockingQueue queue, boolean validate) {
364: if (validate) {
365: assertQueueEqual(Arrays.asList(new Object[] {
366: "Second element", "Third element",
367: "Fourth element", "Fifth element" }), queue);
368: } else {
369: try {
370: Assert.assertEquals(null, queue.poll(10,
371: TimeUnit.MILLISECONDS));
372: } catch (InterruptedException e) {
373: throw new TCRuntimeException(e);
374: }
375: try {
376: queue.put("First element");
377: queue.put("Second element");
378: queue.put("Third element");
379: queue.put("Fourth element");
380: queue.put("Fifth element");
381: } catch (InterruptedException e) {
382: throw new TCRuntimeException(e);
383: }
384:
385: Assert.assertEquals("First element", queue.poll());
386: }
387: }
388:
389: void testPollTimeout2(LinkedBlockingQueue queue, boolean validate) {
390: if (validate) {
391: assertEmptyQueue(queue);
392: } else {
393: Thread thread = new Thread(new QueuePutter(queue,
394: localBarrier));
395: thread.start();
396: try {
397: localBarrier.await();
398: Assert.assertEquals("New element", queue.poll(100,
399: TimeUnit.SECONDS));
400: } catch (Exception e) {
401: throw new TCRuntimeException(e);
402: }
403: }
404: }
405:
406: void testTake(LinkedBlockingQueue queue, boolean validate) {
407: if (!validate) {
408: Thread thread = new Thread(new QueuePutter(queue,
409: localBarrier));
410: thread.start();
411:
412: Object queueElement = null;
413: try {
414: localBarrier.await();
415: queueElement = queue.take();
416: } catch (Exception e) {
417: throw new TCRuntimeException(e);
418: }
419:
420: Assert.assertEquals("New element", queueElement);
421: }
422: }
423:
424: void testRemove1(LinkedBlockingQueue queue, boolean validate) {
425: if (validate) {
426: assertQueueEqual(Arrays
427: .asList(new Object[] { "Second element",
428: "Third element", "Fourth element" }), queue);
429: } else {
430: try {
431: queue.put("First element");
432: queue.put("Second element");
433: queue.put("Third element");
434: queue.put("Fourth element");
435: } catch (InterruptedException e) {
436: throw new TCRuntimeException(e);
437: }
438:
439: queue.remove();
440: }
441: }
442:
443: void testRemove2(LinkedBlockingQueue queue, boolean validate) {
444: if (validate) {
445: assertQueueEqual(Arrays
446: .asList(new Object[] { "First element",
447: "Second element", "Fourth element" }),
448: queue);
449: } else {
450: try {
451: queue.put("First element");
452: queue.put("Second element");
453: queue.put("Third element");
454: queue.put("Fourth element");
455: } catch (InterruptedException e) {
456: throw new TCRuntimeException(e);
457: }
458:
459: queue.remove("Third element");
460: }
461: }
462:
463: void testRemove3(LinkedBlockingQueue queue, boolean validate) {
464: if (validate) {
465: assertQueueEqual(Arrays.asList(new Object[] {
466: "First element", "Second element", "Third element",
467: "Fourth element" }), queue);
468: } else {
469: try {
470: queue.put("First element");
471: queue.put("Second element");
472: queue.put("Third element");
473: queue.put("Fourth element");
474: } catch (InterruptedException e) {
475: throw new TCRuntimeException(e);
476: }
477:
478: queue.remove("Fifth element");
479: }
480: }
481:
482: void testRemoveAll(LinkedBlockingQueue queue, boolean validate) {
483: if (validate) {
484: assertQueueEqual(Arrays.asList(new Object[] {
485: "First element", "Fourth element" }), queue);
486: } else {
487: try {
488: queue.put("First element");
489: queue.put("Second element");
490: queue.put("Third element");
491: queue.put("Fourth element");
492: } catch (InterruptedException e) {
493: throw new TCRuntimeException(e);
494: }
495:
496: List toRemove = new ArrayList();
497: toRemove.add("Second element");
498: toRemove.add("Third element");
499: queue.removeAll(toRemove);
500: }
501: }
502:
503: void testToArray1(LinkedBlockingQueue queue, boolean validate) {
504: if (validate) {
505: assertQueueEqual(Arrays.asList(new Object[] {
506: "First element", "Second element", "Third element",
507: "Fourth element" }), queue);
508: } else {
509: try {
510: queue.put("First element");
511: queue.put("Second element");
512: queue.put("Third element");
513: queue.put("Fourth element");
514: } catch (InterruptedException e) {
515: throw new TCRuntimeException(e);
516: }
517:
518: Object[] array = queue.toArray();
519: assertQueueEqual(Arrays.asList(array), queue);
520: }
521: }
522:
523: void testToArray2(LinkedBlockingQueue queue, boolean validate) {
524: if (validate) {
525: assertQueueEqual(Arrays.asList(new Object[] {
526: "First element", "Second element", "Third element",
527: "Fourth element" }), queue);
528: } else {
529: try {
530: queue.put("First element");
531: queue.put("Second element");
532: queue.put("Third element");
533: queue.put("Fourth element");
534: } catch (InterruptedException e) {
535: throw new TCRuntimeException(e);
536: }
537:
538: Object[] array = new Object[queue.size()];
539: Object[] array2 = queue.toArray(array);
540: Assert.assertTrue(array == array2);
541: assertQueueEqual(Arrays.asList(array), queue);
542: }
543: }
544:
545: void testToArrayWithSharedArray(LinkedBlockingQueue queue,
546: boolean validate) {
547: Object[] array = getArray(queue);
548: if (validate) {
549: assertQueueEqual(Arrays.asList(new Object[] {
550: "First element", "Second element", "Third element",
551: "Fourth element" }), queue);
552: assertQueueEqual(Arrays.asList(array), queue);
553: } else {
554: try {
555: queue.put("First element");
556: queue.put("Second element");
557: queue.put("Third element");
558: queue.put("Fourth element");
559: } catch (InterruptedException e) {
560: throw new TCRuntimeException(e);
561: }
562:
563: // Since the implementation of queue.toArray() is protected by an ReentrantLock, no
564: // synchronization is needed on the array object.
565: Object[] array2 = null;
566: array2 = queue.toArray(array);
567: Assert.assertTrue(array == array2);
568: }
569: }
570:
571: // Read Only test.
572: void testReadOnlyDrainTo(LinkedBlockingQueue queue, boolean validate) {
573: Collection collection = getCollection(queue);
574: if (validate) {
575: assertEmptyQueue(queue);
576: Assert.assertEquals(0, collection.size());
577: } else {
578: try {
579: queue.put("First element");
580: queue.put("Second element");
581: } catch (InterruptedException e) {
582: throw new TCRuntimeException(e);
583: }
584: synchronized (collection) {
585: try {
586: queue.drainTo(collection);
587: throw new AssertionError(
588: "Should have thrown a ReadOnlyException");
589: } catch (ReadOnlyException t) {
590: // Expected
591: }
592: }
593: }
594: }
595:
596: void testIteratorRemove(LinkedBlockingQueue queue, boolean validate) {
597: if (validate) {
598: assertQueueEqual(Arrays.asList(new Object[] {
599: "First element", "Third element" }), queue);
600: } else {
601: try {
602: queue.put("First element");
603: queue.put("Second element");
604: queue.put("Third element");
605: } catch (InterruptedException e) {
606: throw new TCRuntimeException(e);
607: }
608: Iterator itr = queue.iterator();
609: itr.next();
610: itr.next();
611: synchronized (itr) {
612: itr.remove();
613: }
614: }
615: }
616:
617: public static void visitL1DSOConfig(ConfigVisitor visitor,
618: DSOClientConfigHelper config) {
619: String testClass = GenericQueueTestApp.class.getName();
620: TransparencyClassSpec spec = config.getOrCreateSpec(testClass);
621: spec.addRoot("localBarrier", "localBarrier");
622: String writeAllowedMethodExpression = "* " + testClass
623: + "*.*(..)";
624: config.addWriteAutolock(writeAllowedMethodExpression);
625: String readOnlyMethodExpression = "* " + testClass
626: + "*.*ReadOnly*(..)";
627: config.addReadAutolock(readOnlyMethodExpression);
628: }
629:
630: private Collection getCollection(LinkedBlockingQueue queue) {
631: if (queue.remainingCapacity() == 5) {
632: return (Collection) sharedMap
633: .get("collectionForBlockingQueue2");
634: } else {
635: return (Collection) sharedMap
636: .get("collectionForBlockingQueue");
637: }
638: }
639:
640: private Object[] getArray(LinkedBlockingQueue queue) {
641: if (queue.remainingCapacity() == 5) {
642: return (Object[]) sharedMap.get("arrayForBlockingQueue2");
643: } else {
644: return (Object[]) sharedMap.get("arrayForBlockingQueue");
645: }
646: }
647:
648: private void assertEmptyQueue(LinkedBlockingQueue queue) {
649: Assert.assertEquals(0, queue.size());
650: }
651:
652: private void assertSingleElement(Object expected,
653: LinkedBlockingQueue queue) {
654: Assert.assertEquals(1, queue.size());
655: Assert.assertEquals(expected, queue.peek());
656: }
657:
658: private void assertCollectionEqual(Collection expect,
659: Collection actual) {
660: Assert.assertEquals(expect.size(), actual.size());
661:
662: Assert.assertTrue(expect.containsAll(actual));
663: Assert.assertTrue(actual.containsAll(expect));
664: }
665:
666: private void assertQueueEqual(List expect,
667: LinkedBlockingQueue actual) {
668: Assert.assertEquals(expect.size(), actual.size());
669:
670: Assert.assertTrue(expect.containsAll(actual));
671: Assert.assertTrue(actual.containsAll(expect));
672:
673: for (Iterator iExpect = expect.iterator(), iActual = actual
674: .iterator(); iExpect.hasNext();) {
675: Assert.assertEquals(iExpect.next(), iActual.next());
676: }
677:
678: if (expect.isEmpty()) {
679: Assert.assertTrue(actual.isEmpty());
680: } else {
681: Assert.assertFalse(actual.isEmpty());
682: }
683: }
684:
685: private static class QueuePutter implements Runnable {
686: private LinkedBlockingQueue queue;
687: private CyclicBarrier barrier;
688:
689: public QueuePutter(LinkedBlockingQueue queue,
690: CyclicBarrier barrier) {
691: this .queue = queue;
692: this .barrier = barrier;
693: }
694:
695: public void run() {
696: try {
697: queue.put("New element");
698: barrier.await();
699: } catch (Exception e) {
700: throw new TCRuntimeException(e);
701: }
702: }
703: }
704:
705: private static class QueueReader implements Runnable {
706: private LinkedBlockingQueue queue;
707: private CyclicBarrier barrier;
708:
709: public QueueReader(LinkedBlockingQueue queue,
710: CyclicBarrier barrier) {
711: this .queue = queue;
712: this .barrier = barrier;
713: }
714:
715: public void run() {
716: queue.poll();
717: try {
718: barrier.await();
719: } catch (Exception e) {
720: throw new TCRuntimeException(e);
721: }
722: }
723: }
724: }
|