KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > collections > test > CollectionTest


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002,2006 Oracle. All rights reserved.
5  *
6  * $Id: CollectionTest.java,v 1.53 2006/10/30 21:14:38 bostic Exp $
7  */

8
9 package com.sleepycat.collections.test;
10
11 import java.util.ArrayList JavaDoc;
12 import java.util.Collection JavaDoc;
13 import java.util.Collections JavaDoc;
14 import java.util.Enumeration JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18 import java.util.ListIterator JavaDoc;
19 import java.util.Map JavaDoc;
20 import java.util.NoSuchElementException JavaDoc;
21 import java.util.Set JavaDoc;
22 import java.util.SortedMap JavaDoc;
23 import java.util.SortedSet JavaDoc;
24
25 import junit.framework.Test;
26 import junit.framework.TestCase;
27 import junit.framework.TestSuite;
28
29 import com.sleepycat.bind.EntityBinding;
30 import com.sleepycat.bind.EntryBinding;
31 import com.sleepycat.collections.MapEntryParameter;
32 import com.sleepycat.collections.StoredCollection;
33 import com.sleepycat.collections.StoredCollections;
34 import com.sleepycat.collections.StoredContainer;
35 import com.sleepycat.collections.StoredEntrySet;
36 import com.sleepycat.collections.StoredIterator;
37 import com.sleepycat.collections.StoredKeySet;
38 import com.sleepycat.collections.StoredList;
39 import com.sleepycat.collections.StoredMap;
40 import com.sleepycat.collections.StoredSortedEntrySet;
41 import com.sleepycat.collections.StoredSortedKeySet;
42 import com.sleepycat.collections.StoredSortedMap;
43 import com.sleepycat.collections.StoredSortedValueSet;
44 import com.sleepycat.collections.StoredValueSet;
45 import com.sleepycat.collections.TransactionRunner;
46 import com.sleepycat.collections.TransactionWorker;
47 import com.sleepycat.compat.DbCompat;
48 import com.sleepycat.je.Database;
49 import com.sleepycat.je.DatabaseException;
50 import com.sleepycat.je.Environment;
51 import com.sleepycat.util.ExceptionUnwrapper;
52
53 /**
54  * @author Mark Hayes
55  */

56 public class CollectionTest extends TestCase {
57
58     private static final int NONE = 0;
59     private static final int SUB = 1;
60     private static final int HEAD = 2;
61     private static final int TAIL = 3;
62
63     /*
64      * For long tests we permute testStoredIterator to test both StoredIterator
65      * and BlockIterator. When testing BlockIterator, we permute the maxKey
66      * over the array values below. BlockIterator's block size is 10. So we
67      * test below the block size (6), at the block size (10), and above it (14
68      * and 22).
69      */

70     private static final int DEFAULT_MAX_KEY = 6;
71     private static final int[] MAX_KEYS = {6, 10, 14, 22};
72
73     private boolean testStoredIterator;
74     private int maxKey; /* Must be a multiple of 2. */
75     private int beginKey = 1;
76     private int endKey;
77
78     private Environment env;
79     private Database store;
80     private Database index;
81     private boolean isEntityBinding;
82     private boolean isAutoCommit;
83     private TestStore testStore;
84     private String JavaDoc testName;
85     private EntryBinding keyBinding;
86     private EntryBinding valueBinding;
87     private EntityBinding entityBinding;
88     private TransactionRunner readRunner;
89     private TransactionRunner writeRunner;
90     private TransactionRunner writeIterRunner;
91     private TestEnv testEnv;
92
93     private StoredMap map;
94     private StoredMap imap; // insertable map (primary store for indexed map)
95
private StoredSortedMap smap; // sorted map (null or equal to map)
96
private StoredMap saveMap;
97     private StoredSortedMap saveSMap;
98     private int rangeType;
99     private StoredList list;
100     private StoredList ilist; // insertable list (primary store for index list)
101
private StoredList saveList;
102     private StoredKeySet keySet;
103     private StoredValueSet valueSet;
104
105     /**
106      * Runs a command line collection test.
107      * @see #usage
108      */

109     public static void main(String JavaDoc[] args)
110         throws Exception JavaDoc {
111
112         if (args.length == 1 &&
113             (args[0].equals("-h") || args[0].equals("-help"))) {
114             usage();
115         } else {
116             junit.framework.TestResult tr =
117         junit.textui.TestRunner.run(suite(args));
118         if (tr.errorCount() > 0 ||
119         tr.failureCount() > 0) {
120         System.exit(1);
121         } else {
122         System.exit(0);
123         }
124         }
125     }
126
127     private static void usage() {
128
129         System.out.println(
130             "Usage: java com.sleepycat.collections.test.CollectionTest\n" +
131             " -h | -help\n" +
132             " [testName]...\n" +
133             " where testName has the format:\n" +
134             " <env>-<store>-{entity|value}\n" +
135             " <env> is:\n" +
136             " bdb | cdb | txn\n" +
137             " <store> is:\n" +
138             " btree-uniq | btree-dup | btree-dupsort | btree-recnum |\n" +
139             " hash-uniq | hash-dup | hash-dupsort |\n" +
140             " queue | recno | recno-renum\n" +
141             " For example: bdb-btree-uniq-entity\n" +
142             " If no arguments are given then all tests are run.");
143         System.exit(2);
144     }
145
146     public static Test suite()
147         throws Exception JavaDoc {
148
149         return suite(null);
150     }
151
152     static Test suite(String JavaDoc[] args)
153         throws Exception JavaDoc {
154
155         if ("true".equals(System.getProperty("longtest"))) {
156             TestSuite suite = new TestSuite();
157
158             /* StoredIterator tests. */
159             permuteTests(args, suite, true, DEFAULT_MAX_KEY);
160
161             /* BlockIterator tests with different maxKey values. */
162             for (int i = 0; i < MAX_KEYS.length; i += 1) {
163                 permuteTests(args, suite, false, MAX_KEYS[i]);
164             }
165
166             return suite;
167         } else {
168             return baseSuite(args);
169         }
170     }
171
172     private static void permuteTests(String JavaDoc[] args,
173                                      TestSuite suite,
174                                      boolean storedIter,
175                                      int maxKey)
176         throws Exception JavaDoc {
177
178         TestSuite baseTests = baseSuite(args);
179         Enumeration JavaDoc e = baseTests.tests();
180         while (e.hasMoreElements()) {
181             CollectionTest t = (CollectionTest) e.nextElement();
182             t.setParams(storedIter, maxKey);
183             suite.addTest(t);
184         }
185     }
186
187     private static TestSuite baseSuite(String JavaDoc[] args)
188         throws Exception JavaDoc {
189
190         TestSuite suite = new TestSuite();
191         for (int i = 0; i < TestEnv.ALL.length; i += 1) {
192             for (int j = 0; j < TestStore.ALL.length; j += 1) {
193                 for (int k = 0; k < 2; k += 1) {
194                     boolean entityBinding = (k != 0);
195
196                     addTest(args, suite, new CollectionTest(
197                             TestEnv.ALL[i], TestStore.ALL[j],
198                             entityBinding, false));
199
200                     if (TestEnv.ALL[i].isTxnMode()) {
201                         addTest(args, suite, new CollectionTest(
202                                 TestEnv.ALL[i], TestStore.ALL[j],
203                                 entityBinding, true));
204                     }
205                 }
206             }
207         }
208         return suite;
209     }
210
211     private static void addTest(String JavaDoc[] args, TestSuite suite,
212                                 CollectionTest test) {
213
214         if (args == null || args.length == 0) {
215             suite.addTest(test);
216         } else {
217             for (int t = 0; t < args.length; t += 1) {
218                 if (args[t].equals(test.testName)) {
219                     suite.addTest(test);
220                     break;
221                 }
222             }
223         }
224     }
225
226     public CollectionTest(TestEnv testEnv, TestStore testStore,
227                           boolean isEntityBinding, boolean isAutoCommit) {
228
229         super(null);
230
231         this.testEnv = testEnv;
232         this.testStore = testStore;
233         this.isEntityBinding = isEntityBinding;
234         this.isAutoCommit = isAutoCommit;
235
236         keyBinding = testStore.getKeyBinding();
237         valueBinding = testStore.getValueBinding();
238         entityBinding = testStore.getEntityBinding();
239
240         setParams(false, DEFAULT_MAX_KEY);
241     }
242
243     private void setParams(boolean storedIter, int maxKey) {
244
245         this.testStoredIterator = storedIter;
246         this.maxKey = maxKey;
247         this.endKey = maxKey;
248
249         testName = testEnv.getName() + '-' + testStore.getName() +
250                     (isEntityBinding ? "-entity" : "-value") +
251                     (isAutoCommit ? "-autoCommit" : "") +
252                     (testStoredIterator ? "-storedIter" : "") +
253                     ((maxKey != DEFAULT_MAX_KEY) ? ("-maxKey-" + maxKey) : "");
254     }
255     
256     public void tearDown()
257         throws Exception JavaDoc {
258
259         setName(testName);
260     }
261
262     public void runTest()
263         throws Exception JavaDoc {
264
265         DbTestUtil.printTestName(DbTestUtil.qualifiedTestName(this));
266         try {
267             env = testEnv.open(testName);
268
269             // For testing auto-commit, use a normal (transactional) runner for
270
// all reading and for writing via an iterator, and a do-nothing
271
// runner for writing via collections; if auto-commit is tested,
272
// the per-collection auto-commit property will be set elsewhere.
273
//
274
TransactionRunner normalRunner = newTransactionRunner(env);
275             normalRunner.setAllowNestedTransactions(
276                     DbCompat.NESTED_TRANSACTIONS);
277             TransactionRunner nullRunner = new NullTransactionRunner(env);
278             readRunner = nullRunner;
279             writeIterRunner = normalRunner;
280             if (isAutoCommit) {
281                 writeRunner = nullRunner;
282             } else {
283                 writeRunner = normalRunner;
284             }
285
286             store = testStore.open(env, "unindexed.db");
287             testUnindexed();
288             store.close();
289             store = null;
290
291             TestStore indexOf = testStore.getIndexOf();
292             if (indexOf != null) {
293                 store = indexOf.open(env, "indexed.db");
294                 index = testStore.openIndex(store, "index.db");
295                 testIndexed();
296                 index.close();
297                 index = null;
298                 store.close();
299                 store = null;
300             }
301             env.close();
302             env = null;
303         } catch (Exception JavaDoc e) {
304             throw ExceptionUnwrapper.unwrap(e);
305         } finally {
306             if (index != null) {
307                 try {
308             index.close();
309         } catch (Exception JavaDoc e) {
310         }
311             }
312             if (store != null) {
313                 try {
314             store.close();
315         } catch (Exception JavaDoc e) {
316         }
317             }
318             if (env != null) {
319                 try {
320             env.close();
321         } catch (Exception JavaDoc e) {
322         }
323             }
324             /* Ensure that GC can cleanup. */
325             index = null;
326             store = null;
327             env = null;
328             readRunner = null;
329             writeRunner = null;
330             writeIterRunner = null;
331             map = null;
332             imap = null;
333             smap = null;
334             saveMap = null;
335             saveSMap = null;
336             list = null;
337             ilist = null;
338             saveList = null;
339             keySet = null;
340             valueSet = null;
341         testEnv = null;
342         testStore = null;
343         }
344     }
345
346     /**
347      * Is overridden in XACollectionTest.
348      */

349     protected TransactionRunner newTransactionRunner(Environment env)
350         throws DatabaseException {
351
352         return new TransactionRunner(env);
353     }
354
355     void testCreation(StoredContainer cont, int expectSize)
356         throws Exception JavaDoc {
357
358         assertEquals(index != null, cont.isSecondary());
359         assertEquals(testStore.isOrdered(), cont.isOrdered());
360         assertEquals(testStore.areKeysRenumbered(), cont.areKeysRenumbered());
361         assertEquals(testStore.areDuplicatesAllowed(),
362                      cont.areDuplicatesAllowed());
363         assertEquals(testEnv.isTxnMode(), cont.isTransactional());
364         assertEquals(expectSize, cont.size());
365     }
366
367     void testMapCreation(Map JavaDoc map)
368         throws Exception JavaDoc {
369
370         assertTrue(map.values() instanceof Set JavaDoc);
371         assertEquals(testStore.isOrdered(),
372                      map.keySet() instanceof SortedSet JavaDoc);
373         assertEquals(testStore.isOrdered(),
374                      map.entrySet() instanceof SortedSet JavaDoc);
375         assertEquals(testStore.isOrdered() && isEntityBinding,
376                      map.values() instanceof SortedSet JavaDoc);
377     }
378
379     void testUnindexed()
380         throws Exception JavaDoc {
381
382         // create primary map
383
if (testStore.isOrdered()) {
384             if (isEntityBinding) {
385                 smap = new StoredSortedMap(store, keyBinding,
386                                            entityBinding,
387                                            testStore.getKeyAssigner());
388                 valueSet = new StoredSortedValueSet(store, entityBinding,
389                                                     true);
390             } else {
391                 smap = new StoredSortedMap(store, keyBinding,
392                                            valueBinding,
393                                            testStore.getKeyAssigner());
394                 // sorted value set is not possible since key cannot be derived
395
// for performing subSet, etc.
396
}
397             keySet = new StoredSortedKeySet(store, keyBinding, true);
398             map = smap;
399         } else {
400             if (isEntityBinding) {
401                 map = new StoredMap(store, keyBinding, entityBinding,
402                                     testStore.getKeyAssigner());
403                 valueSet = new StoredValueSet(store, entityBinding, true);
404             } else {
405                 map = new StoredMap(store, keyBinding, valueBinding,
406                                     testStore.getKeyAssigner());
407                 valueSet = new StoredValueSet(store, valueBinding, true);
408             }
409             smap = null;
410             keySet = new StoredKeySet(store, keyBinding, true);
411         }
412         imap = map;
413
414         // create primary list
415
if (testStore.hasRecNumAccess()) {
416             if (isEntityBinding) {
417                 ilist = new StoredList(store, entityBinding,
418                                        testStore.getKeyAssigner());
419             } else {
420                 ilist = new StoredList(store, valueBinding,
421                                        testStore.getKeyAssigner());
422             }
423             list = ilist;
424         } else {
425             try {
426                 if (isEntityBinding) {
427                     ilist = new StoredList(store, entityBinding,
428                                            testStore.getKeyAssigner());
429                 } else {
430                     ilist = new StoredList(store, valueBinding,
431                                            testStore.getKeyAssigner());
432                 }
433                 fail();
434             } catch (IllegalArgumentException JavaDoc expected) {}
435         }
436
437         testCreation(map, 0);
438         if (list != null) {
439             testCreation(list, 0);
440             assertNotNull(smap);
441         }
442         testMapCreation(map);
443         addAll();
444         testAll();
445     }
446
447     void testIndexed()
448         throws Exception JavaDoc {
449
450         // create primary map
451
if (isEntityBinding) {
452             map = new StoredMap(store, keyBinding, entityBinding,
453                                 testStore.getKeyAssigner());
454         } else {
455             map = new StoredMap(store, keyBinding, valueBinding,
456                                 testStore.getKeyAssigner());
457         }
458         imap = map;
459         smap = null;
460         // create primary list
461
if (testStore.hasRecNumAccess()) {
462             if (isEntityBinding) {
463                 list = new StoredList(store, entityBinding,
464                                       testStore.getKeyAssigner());
465             } else {
466                 list = new StoredList(store, valueBinding,
467                                       testStore.getKeyAssigner());
468             }
469             ilist = list;
470         }
471
472         addAll();
473         readAll();
474
475         // create indexed map (keySet/valueSet)
476
if (testStore.isOrdered()) {
477             if (isEntityBinding) {
478                 map = smap = new StoredSortedMap(index, keyBinding,
479                                                  entityBinding, true);
480                 valueSet = new StoredSortedValueSet(index, entityBinding,
481                                                     true);
482             } else {
483                 map = smap = new StoredSortedMap(index, keyBinding,
484                                                  valueBinding, true);
485                 // sorted value set is not possible since key cannot be derived
486
// for performing subSet, etc.
487
}
488             keySet = new StoredSortedKeySet(index, keyBinding, true);
489         } else {
490             if (isEntityBinding) {
491                 map = new StoredMap(index, keyBinding, entityBinding, true);
492                 valueSet = new StoredValueSet(index, entityBinding, true);
493             } else {
494                 map = new StoredMap(index, keyBinding, valueBinding, true);
495                 valueSet = new StoredValueSet(index, valueBinding, true);
496             }
497             smap = null;
498             keySet = new StoredKeySet(index, keyBinding, true);
499         }
500
501         // create indexed list
502
if (testStore.hasRecNumAccess()) {
503             if (isEntityBinding) {
504                 list = new StoredList(index, entityBinding, true);
505             } else {
506                 list = new StoredList(index, valueBinding, true);
507             }
508         } else {
509             try {
510                 if (isEntityBinding) {
511                     list = new StoredList(index, entityBinding, true);
512                 } else {
513                     list = new StoredList(index, valueBinding, true);
514                 }
515                 fail();
516             }
517             catch (IllegalArgumentException JavaDoc expected) {}
518         }
519
520         testCreation(map, maxKey);
521         testCreation((StoredContainer) map.values(), maxKey);
522         testCreation((StoredContainer) map.keySet(), maxKey);
523         testCreation((StoredContainer) map.entrySet(), maxKey);
524         if (list != null) {
525             testCreation(list, maxKey);
526             assertNotNull(smap);
527         }
528         testMapCreation(map);
529         testAll();
530     }
531
532     void testAll()
533         throws Exception JavaDoc {
534
535         checkKeySetAndValueSet();
536         readAll();
537         updateAll();
538         readAll();
539         if (!map.areKeysRenumbered()) {
540             removeOdd();
541             readEven();
542             addOdd();
543             readAll();
544             removeOddIter();
545             readEven();
546             if (imap.areDuplicatesAllowed()) {
547                 addOddDup();
548             } else {
549                 addOdd();
550             }
551             readAll();
552             removeOddEntry();
553             readEven();
554             addOdd();
555             readAll();
556             if (isEntityBinding) {
557                 removeOddEntity();
558                 readEven();
559                 addOddEntity();
560                 readAll();
561             }
562             bulkOperations();
563         }
564         if (isListAddAllowed()) {
565             removeOddList();
566             readEvenList();
567             addOddList();
568             readAll();
569             if (!isEntityBinding) {
570                 removeOddListValue();
571                 readEvenList();
572                 addOddList();
573                 readAll();
574             }
575         }
576         if (list != null) {
577             bulkListOperations();
578         } else {
579             listOperationsNotAllowed();
580         }
581         if (smap != null) {
582             readWriteRange(SUB, 1, 1);
583             readWriteRange(HEAD, 1, 1);
584             readWriteRange(SUB, 1, maxKey);
585             readWriteRange(HEAD, 1, maxKey);
586             readWriteRange(TAIL, 1, maxKey);
587             readWriteRange(SUB, 1, 3);
588             readWriteRange(HEAD, 1, 3);
589             readWriteRange(SUB, 2, 2);
590             readWriteRange(SUB, 2, maxKey);
591             readWriteRange(TAIL, 2, maxKey);
592             readWriteRange(SUB, maxKey, maxKey);
593             readWriteRange(TAIL, maxKey, maxKey);
594             readWriteRange(SUB, maxKey + 1, maxKey + 1);
595             readWriteRange(TAIL, maxKey + 1, maxKey + 1);
596             readWriteRange(SUB, 0, 0);
597             readWriteRange(HEAD, 0, 0);
598         }
599         updateAll();
600         readAll();
601         if (map.areDuplicatesAllowed()) {
602             readWriteDuplicates();
603             readAll();
604         } else {
605             duplicatesNotAllowed();
606             readAll();
607         }
608         if (testEnv.isCdbMode()) {
609             testCdbLocking();
610         }
611         removeAll();
612         if (isListAddAllowed()) {
613             testIterAddList();
614             clearAll();
615         }
616         if (imap.areDuplicatesAllowed()) {
617             testIterAddDuplicates();
618             clearAll();
619         }
620         if (isListAddAllowed()) {
621             addAllList();
622             readAll();
623             removeAllList();
624         }
625         appendAll();
626     }
627
628     void checkKeySetAndValueSet() {
629
630         // use bulk operations to check that explicitly constructed
631
// keySet/valueSet are equivalent
632
assertTrue(imap.keySet().equals(keySet));
633         if (valueSet != null) {
634             assertTrue(imap.values().equals(valueSet));
635         }
636     }
637
638     Iterator JavaDoc iterator(Collection JavaDoc storedCollection) {
639
640         if (testStoredIterator) {
641             return ((StoredCollection) storedCollection).storedIterator();
642         } else {
643             return storedCollection.iterator();
644         }
645     }
646
647     void addAll()
648         throws Exception JavaDoc {
649
650         writeRunner.run(new TransactionWorker() {
651             public void doWork() throws Exception JavaDoc {
652                 assertTrue(imap.isEmpty());
653                 Iterator JavaDoc iter = iterator(imap.entrySet());
654                 try {
655                     assertTrue(!iter.hasNext());
656                 } finally {
657                     StoredIterator.close(iter);
658                 }
659                 assertEquals(0, imap.keySet().toArray().length);
660                 assertEquals(0, imap.keySet().toArray(new Object JavaDoc[0]).length);
661                 assertEquals(0, imap.entrySet().toArray().length);
662                 assertEquals(0, imap.entrySet().toArray(new Object JavaDoc[0]).length);
663                 assertEquals(0, imap.values().toArray().length);
664                 assertEquals(0, imap.values().toArray(new Object JavaDoc[0]).length);
665
666                 for (int i = beginKey; i <= endKey; i += 1) {
667                     Long JavaDoc key = makeKey(i);
668                     Object JavaDoc val = makeVal(i);
669                     assertNull(imap.get(key));
670                     assertTrue(!imap.keySet().contains(key));
671                     assertTrue(!imap.values().contains(val));
672                     assertNull(imap.put(key, val));
673                     assertEquals(val, imap.get(key));
674                     assertTrue(imap.keySet().contains(key));
675                     assertTrue(imap.values().contains(val));
676                     assertTrue(imap.duplicates(key).contains(val));
677                     if (!imap.areDuplicatesAllowed()) {
678                         assertEquals(val, imap.put(key, val));
679                     }
680                     checkDupsSize(1, imap.duplicates(key));
681                 }
682                 assertTrue(!imap.isEmpty());
683             }
684         });
685     }
686
687     void appendAll()
688         throws Exception JavaDoc {
689
690         writeRunner.run(new TransactionWorker() {
691             public void doWork() throws Exception JavaDoc {
692                 assertTrue(imap.isEmpty());
693
694                 TestKeyAssigner keyAssigner = testStore.getKeyAssigner();
695                 if (keyAssigner != null) {
696                     keyAssigner.reset();
697                 }
698
699                 for (int i = beginKey; i <= endKey; i += 1) {
700                     boolean useList = (i & 1) == 0;
701                     Long JavaDoc key = makeKey(i);
702                     Object JavaDoc val = makeVal(i);
703                     assertNull(imap.get(key));
704                     if (keyAssigner != null) {
705                         if (useList && ilist != null) {
706                             assertEquals(i - 1, ilist.append(val));
707                         } else {
708                             assertEquals(key, imap.append(val));
709                         }
710                         assertEquals(val, imap.get(key));
711                     } else {
712                         Long JavaDoc recnoKey;
713                         if (useList && ilist != null) {
714                             recnoKey = new Long JavaDoc(ilist.append(val) + 1);
715                         } else {
716                             recnoKey = (Long JavaDoc) imap.append(val);
717                         }
718                         assertNotNull(recnoKey);
719                         Object JavaDoc recnoVal;
720                         if (isEntityBinding) {
721                             recnoVal = makeEntity(recnoKey.intValue(), i);
722                         } else {
723                             recnoVal = val;
724                         }
725                         assertEquals(recnoVal, imap.get(recnoKey));
726                     }
727                 }
728             }
729         });
730