001: /*
002: * $Id: TestIntBTree.java,v 1.6 2005/05/02 22:32:01 ahimanikya Exp $
003: * =======================================================================
004: * Copyright (c) 2002-2003 Axion Development Team. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * 1. Redistributions of source code must retain the above
011: * copyright notice, this list of conditions and the following
012: * disclaimer.
013: *
014: * 2. Redistributions in binary form must reproduce the above copyright
015: * notice, this list of conditions and the following disclaimer in
016: * the documentation and/or other materials provided with the
017: * distribution.
018: *
019: * 3. The names "Tigris", "Axion", nor the names of its contributors may
020: * not be used to endorse or promote products derived from this
021: * software without specific prior written permission.
022: *
023: * 4. Products derived from this software may not be called "Axion", nor
024: * may "Tigris" or "Axion" appear in their names without specific prior
025: * written permission.
026: *
027: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
028: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
029: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
030: * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
031: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
032: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
033: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
034: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
035: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
036: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
037: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
038: * =======================================================================
039: */
040:
041: package org.axiondb.util;
042:
043: import java.io.File;
044: import java.util.ArrayList;
045: import java.util.HashMap;
046: import java.util.HashSet;
047: import java.util.Iterator;
048: import java.util.List;
049: import java.util.Map;
050: import java.util.NoSuchElementException;
051: import java.util.Random;
052: import java.util.Set;
053:
054: import junit.framework.Test;
055: import junit.framework.TestSuite;
056:
057: import org.apache.commons.collections.primitives.ArrayIntList;
058: import org.apache.commons.collections.primitives.IntIterator;
059: import org.apache.commons.collections.primitives.IntList;
060: import org.apache.commons.collections.primitives.IntListIterator;
061: import org.apache.commons.logging.Log;
062: import org.apache.commons.logging.LogFactory;
063: import org.axiondb.AbstractDbdirTest;
064:
065: /**
066: * @version $Revision: 1.6 $ $Date: 2005/05/02 22:32:01 $
067: * @author Chuck Burdick
068: * @author Dave Pekarek Krohn
069: * @author Rod Waldhoff
070: */
071: public class TestIntBTree extends AbstractDbdirTest {
072: private static Log _log = LogFactory.getLog(TestIntBTree.class);
073: private IntBTree _tree = null;
074: private int _deg = 3;
075: private int _max = (int) Math.pow(2 * _deg, 2);
076: private Random _random = new Random();
077:
078: //------------------------------------------------------------ Conventional
079:
080: public TestIntBTree(String testName) {
081: super (testName);
082: }
083:
084: public static void main(String args[]) {
085: String[] testCaseName = { TestIntBTree.class.getName() };
086: junit.textui.TestRunner.main(testCaseName);
087: }
088:
089: public static Test suite() {
090: return new TestSuite(TestIntBTree.class);
091: }
092:
093: //--------------------------------------------------------------- Lifecycle
094:
095: public void setUp() throws Exception {
096: super .setUp();
097: long newSeed = _random.nextLong();
098: _log.debug("New Seed: " + newSeed);
099: _random.setSeed(newSeed);
100: _tree = new IntBTree(getDbdir(), "idx", _deg);
101: }
102:
103: public void tearDown() throws Exception {
104: _tree = null;
105: super .tearDown();
106: }
107:
108: //------------------------------------------------------------------- Tests
109:
110: public void testCreate() throws Exception {
111: assertTrue("Should have dbdir avail", getDbdir().exists());
112: assertTrue("Dbdir should be directory", getDbdir()
113: .isDirectory());
114: assertNotNull("Should not be null", _tree);
115: assertTrue("Should be leaf", _tree.isLeaf());
116: assertEquals("Should have no entries", 0, _tree.size());
117: File idx = new File(getDbdir(), "IDX" + ".0");
118: assertTrue("Should not have an index file before save", !idx
119: .exists());
120: _tree.insert(1, 1);
121: _tree.save(getDbdir());
122: assertTrue("Should have an index file after save", idx.exists());
123: }
124:
125: public void testValueIteratorGreaterThan() throws Exception {
126: for (int i = 0; i < _max; i++) {
127: _tree.insert(i, i);
128: }
129: for (int j = 0; j < _max; j++) {
130: IntListIterator iter = _tree
131: .valueIteratorGreaterThan(j - 1);
132: assertTrue(!iter.hasPrevious());
133: for (int i = j; i < _max; i++) {
134: assertTrue(iter.hasNext());
135: assertEquals(j + "," + i, i, iter.next());
136: }
137: assertTrue(!iter.hasNext());
138: for (int i = _max - 1; i >= j; i--) {
139: assertTrue(iter.hasPrevious());
140: assertEquals(i, iter.previous());
141: }
142: assertTrue(!iter.hasPrevious());
143: }
144: }
145:
146: public void testGetAllFrom() throws Exception {
147: for (int i = 0; i < _max; i++) {
148: _tree.insert(i, i);
149: }
150: for (int j = 0; j < _max; j++) {
151: IntListIterator iter = _tree.getAllFrom(j);
152: assertTrue(!iter.hasPrevious());
153: for (int i = j; i < _max; i++) {
154: assertTrue(iter.hasNext());
155: assertEquals(j + "," + i, i, iter.next());
156: }
157: assertTrue(!iter.hasNext());
158: for (int i = _max - 1; i >= j; i--) {
159: assertTrue(iter.hasPrevious());
160: assertEquals(j + "," + i, i, iter.previous());
161: }
162: assertTrue(!iter.hasPrevious());
163: }
164: }
165:
166: public void testEmptyValueIteratorGreaterThan() throws Exception {
167: for (int i = 0; i < 10; i++) {
168: _tree.insert(i, i);
169: }
170: IntListIterator iter = _tree.valueIteratorGreaterThan(9);
171: assertTrue(!iter.hasNext());
172: assertTrue(!iter.hasPrevious());
173: }
174:
175: public void testCompleteValueIteratorGreaterThan() throws Exception {
176: for (int i = 0; i < 10; i++) {
177: _tree.insert(i, i);
178: }
179: IntListIterator iter = _tree.valueIteratorGreaterThan(-1);
180: for (int i = 0; i < 10; i++) {
181: assertTrue(iter.hasNext());
182: assertEquals(i, iter.next());
183: }
184: assertTrue(!iter.hasNext());
185: for (int i = 9; i >= 0; i--) {
186: assertTrue(iter.hasPrevious());
187: assertEquals(i, iter.previous());
188: }
189: assertTrue(!iter.hasPrevious());
190: }
191:
192: public void testValueIterator() throws Exception {
193: for (int i = 0; i < 10; i++) {
194: _tree.insert(i, i);
195: }
196: IntListIterator iter = _tree.valueIterator();
197: for (int i = 0; i < 10; i++) {
198: assertTrue(iter.hasNext());
199: assertEquals(i, iter.next());
200: }
201: assertTrue(!iter.hasNext());
202: for (int i = 9; i >= 0; i--) {
203: assertTrue(iter.hasPrevious());
204: assertEquals(i, iter.previous());
205: }
206: assertTrue(!iter.hasPrevious());
207: }
208:
209: public void testValueIteratorLong() throws Exception {
210: for (int i = 0; i < _max; i++) {
211: _tree.insert(i, i);
212: }
213: IntListIterator iter = _tree.valueIterator();
214: for (int i = 0; i < _max; i++) {
215: assertTrue(iter.hasNext());
216: assertEquals(i, iter.next());
217: }
218: assertTrue(!iter.hasNext());
219: for (int i = _max - 1; i >= 0; i--) {
220: assertTrue(iter.hasPrevious());
221: assertEquals(i, iter.previous());
222: }
223: assertTrue(!iter.hasPrevious());
224: }
225:
226: public void testEmptyValueIterator() throws Exception {
227: IntIterator iter = _tree.valueIterator();
228: assertTrue(!iter.hasNext());
229: try {
230: iter.next();
231: fail("Expected NoSuchElementException");
232: } catch (NoSuchElementException e) {
233: // expected
234: }
235: }
236:
237: public void testSingleValueIterator() throws Exception {
238: _tree.insert(0, 1);
239: IntIterator iter = _tree.valueIterator();
240: assertTrue(iter.hasNext());
241: assertEquals(1, iter.next());
242: assertTrue(!iter.hasNext());
243: }
244:
245: public void testInsertAndRetrieve() throws Exception {
246: _tree.insert(123, 456);
247: assertTrue("Tree should be valid after insert", _tree.isValid());
248: assertEquals("Should have one value", 1, _tree.size());
249: assertEquals("Should get value back", new Integer(456), _tree
250: .get(123));
251: }
252:
253: public void testInsertAndRetrieveMany() throws Exception {
254: for (int i = 0; i < _max; i++) {
255: _log.debug("Inserting key " + i);
256: _tree.insert(i, _max - i);
257: _log.debug(_tree.toString());
258: assertTrue("Tree should be valid after insert", _tree
259: .isValid());
260: assertEquals("Should get the value back as inserting for "
261: + i, new Integer(_max - i), _tree.get(i));
262: }
263: for (int i = 0; i < _max; i++) {
264: assertEquals("Should get the value back for " + i,
265: new Integer(_max - i), _tree.get(i));
266: }
267: }
268:
269: public void testInsertIdenticalAndGetAll() throws Exception {
270: _tree = new IntBTree(getDbdir(), "idx", 8);
271: int max = 100;
272: for (int i = 0; i < max; i++) {
273: _log.debug("Inserting key " + i);
274: _tree.insert(i, i);
275: _tree.insert(i, max - i);
276: _tree.insert(i, -1 * i);
277: _log.debug(_tree.toString());
278: assertTrue("Tree should be valid after insert", _tree
279: .isValid());
280: IntIterator iter = _tree.getAll(i);
281: List valList = new ArrayList();
282: valList.add(new Integer(i));
283: valList.add(new Integer(max - i));
284: valList.add(new Integer(-1 * i));
285: for (int j = 0; j < 3; j++) {
286: assertTrue("Should have another value for: " + i, iter
287: .hasNext());
288: Integer val = new Integer(iter.next());
289: assertTrue("Should contain value: " + val + " for: "
290: + i, valList.contains(val));
291: valList.remove(val);
292: }
293: }
294: for (int i = 0; i < max; i++) {
295: IntIterator iter = _tree.getAll(i);
296: List valList = new ArrayList();
297: valList.add(new Integer(i));
298: valList.add(new Integer(max - i));
299: valList.add(new Integer(-1 * i));
300: for (int j = 0; j < 3; j++) {
301: assertTrue("Should have another value for: " + i, iter
302: .hasNext());
303: Integer val = new Integer(iter.next());
304: assertTrue("Should contain value: " + val + " for: "
305: + i, valList.contains(val));
306: valList.remove(val);
307: }
308: }
309: }
310:
311: public void testReloadTree() throws Exception {
312: //Insert a bunch of items
313: {
314: for (int i = 0; i < _max; i++) {
315: _log.debug("Inserting key " + i);
316: _tree.insert(i, _max - i);
317: _log.debug(_tree.toString());
318: assertTrue("Tree should be valid after insert", _tree
319: .isValid());
320: assertEquals(
321: "Should get the value back as inserting for "
322: + i, new Integer(_max - i), _tree
323: .get(i));
324: }
325: _tree.save(getDbdir());
326: }
327:
328: //Reload tree and make sure items are still there
329: //then delete some of them
330: {
331: _tree = new IntBTree(getDbdir(), "idx", _deg);
332: for (int i = 0; i < _max; i++) {
333: assertEquals("Should get the value back for " + i
334: + " from tree: " + _tree,
335: new Integer(_max - i), _tree.get(i));
336: }
337:
338: for (int i = 0; i < _max / 2; i++) {
339: _tree.delete(i, _max - i);
340: assertEquals("Should not get the value back for " + i,
341: null, _tree.get(i));
342: }
343: _tree.save(getDbdir());
344: }
345:
346: //Reload the tree and make sure that items that should be there are there
347: //and those that should not aren't. Then add the deleted items back
348: {
349: _tree = new IntBTree(getDbdir(), "idx", _deg);
350: for (int i = _max / 2; i < _max; i++) {
351: assertEquals("Should get the value back for " + i,
352: new Integer(_max - i), _tree.get(i));
353: }
354:
355: for (int i = 0; i < _max / 2; i++) {
356: assertEquals("Should not get the value back for " + i,
357: null, _tree.get(i));
358: _tree.insert(i, _max - i);
359: }
360: _tree.save(getDbdir());
361: }
362:
363: //Reload the tree and make sure that all items are there
364: {
365: _tree = new IntBTree(getDbdir(), "idx", _deg);
366: for (int i = 0; i < _max; i++) {
367: assertEquals("Should get the value back for " + i,
368: new Integer(_max - i), _tree.get(i));
369: }
370: _tree.save(getDbdir());
371: }
372: }
373:
374: public void testInsertAndRetrieveManyRandom() throws Exception {
375: Map tests = new HashMap();
376: for (int i = 0; i < _max; i++) {
377: Integer key = new Integer(_random.nextInt());
378: Integer value = new Integer(_random.nextInt());
379: if (!tests.containsKey(key)) {
380: tests.put(key, value);
381: _log.debug("Inserting key " + key);
382: _tree.insert(key.intValue(), value.intValue());
383: _log.debug(_tree.toString());
384: assertTrue("Tree should be valid after insert", _tree
385: .isValid());
386: assertEquals("Should get value back as inserting",
387: value, _tree.get(key.intValue()));
388: }
389: }
390: assertEquals("Should have " + _max + " insertions", _max, tests
391: .keySet().size());
392: Iterator i = tests.keySet().iterator();
393: while (i.hasNext()) {
394: Integer cur = (Integer) i.next();
395: assertEquals("Should get value back", tests.get(cur), _tree
396: .get(cur.intValue()));
397: }
398: }
399:
400: public void testInsertAndRetrieveManyIdentical() throws Exception {
401: Set tests = new HashSet();
402: for (int i = 0; i < _max; i++) {
403: _log.debug("Insertion number " + (i + 1));
404: _tree.insert(3, i);
405: assertTrue("Tree should be valid after insert", _tree
406: .isValid());
407: tests.add(new Integer(i));
408: _log.debug(_tree.toString());
409: }
410: assertEquals("Should have full number of tests", _max, tests
411: .size());
412: IntIterator i = _tree.getAll(3);
413: int count = 0;
414: while (i.hasNext()) {
415: tests.remove(new Integer(i.next()));
416: count++;
417: }
418: assertEquals("Should have found all matching inserts", _max,
419: count);
420: assertTrue("All test vals should have been retrieved", tests
421: .isEmpty());
422: i = _tree.getAll(4);
423: assertTrue("Should not have any matches", !i.hasNext());
424: }
425:
426: public void testInsertAndDeleteCaseTests() throws Exception {
427: //Do inserts
428: for (int i = 1; i <= 26; i++) {
429: _log.debug("Inserting key " + i);
430: _tree.insert(i, i);
431: _log.debug(_tree.toString());
432: assertEquals("Should get value back as inserting", i, _tree
433: .get(i).intValue());
434: assertTrue("Tree should be valid after insert", _tree
435: .isValid());
436: }
437:
438: int[] deleteArray = { 6, 13, 7, 2, 5, 21, 14, 11, 1, 4, 25, 23 };
439:
440: for (int i = 0; i < deleteArray.length; i++) {
441: int val = deleteArray[i];
442: assertEquals("Should get value back", val, _tree.get(val)
443: .intValue());
444: _log.debug("Deleting key " + val);
445: _log.debug("Tree before delete: " + _tree.toString());
446: _tree.delete(val, val);
447: _log.debug("Tree after delete: " + _tree.toString());
448: assertTrue("Tree should be valid after delete", _tree
449: .isValid());
450: assertNull("Value should be deleted for key: " + val, _tree
451: .get(val));
452: }
453: }
454:
455: public void testInsertAndDeleteLots() throws Exception {
456: //Do inserts
457: int max = _max * 10;
458: for (int i = 0; i <= max; i++) {
459: _log.debug("Inserting key " + i);
460: _tree.insert(i, i);
461: _log.debug(_tree.toString());
462: assertTrue("Tree should be valid after insert", _tree
463: .isValid());
464: assertEquals("Should get value back as inserting", i, _tree
465: .get(i).intValue());
466: }
467:
468: for (int i = 0; i <= max; i++) {
469: int val = (i + 20) % (max + 1);
470: assertEquals("Should get value back", val, _tree.get(val)
471: .intValue());
472: _log.debug("Deleting key " + val);
473: _log.debug("Tree before delete: " + _tree.toString());
474: _tree.delete(val, val);
475: _log.debug("Tree after delete: " + _tree.toString());
476: assertTrue("Tree should be valid after delete", _tree
477: .isValid());
478: assertNull("Value should be deleted for key: " + val, _tree
479: .get(val));
480: }
481:
482: assertTrue("Tree should be empty", _tree.size() == 0);
483: }
484:
485: public void testInsertAndDeleteLotsWithReload() throws Exception {
486: //Do inserts
487: int max = _max * 10;
488: for (int i = 0; i <= max; i++) {
489: _log.debug("Inserting key " + i);
490: _tree.insert(i, i);
491: _log.debug(_tree.toString());
492: assertTrue("Tree should be valid after insert", _tree
493: .isValid());
494: assertEquals("Should get value back as inserting", i, _tree
495: .get(i).intValue());
496: }
497: _tree.save(getDbdir());
498:
499: _tree = new IntBTree(getDbdir(), "idx", _deg);
500: for (int i = 0; i <= max; i++) {
501: int val = (i + 20) % (max + 1);
502: assertEquals("Should get value back", val, _tree.get(val)
503: .intValue());
504: _log.debug("Deleting key " + val);
505: _log.debug("Tree before delete: " + _tree.toString());
506: _tree.delete(val, val);
507: _log.debug("Tree after delete: " + _tree.toString());
508: assertNull("Value should be deleted for key: " + val, _tree
509: .get(val));
510: }
511: _tree.save(getDbdir());
512:
513: _tree = new IntBTree(getDbdir(), "idx", _deg);
514: assertTrue("Tree should be empty", _tree.size() == 0);
515: }
516:
517: public void testInsertAndDeleteRandom() throws Exception {
518: Map tests = new HashMap();
519: //Do inserts
520: int max = _max * 10;
521: for (int i = 0; i < max; i++) {
522: Integer key = new Integer(_random.nextInt());
523: Integer value = key;
524: if (!tests.containsKey(key)) {
525: tests.put(key, value);
526: _log.debug("Inserting key " + key);
527: _tree.insert(key.intValue(), value.intValue());
528: _log.debug(_tree.toString());
529: assertTrue("Tree should be valid after insert", _tree
530: .isValid());
531: assertEquals("Should get value back as inserting",
532: value, _tree.get(key.intValue()));
533: }
534: }
535: assertEquals("Should have " + max + " insertions", max, tests
536: .keySet().size());
537: //Do deletes
538: Iterator i = tests.keySet().iterator();
539: while (i.hasNext()) {
540: Integer cur = (Integer) i.next();
541: Integer value = (Integer) tests.get(cur);
542: assertEquals("Should get value back", value, _tree.get(cur
543: .intValue()));
544: _log.debug("Deleting key " + cur);
545: _log.debug("Tree before delete: " + _tree.toString());
546: _tree.delete(cur.intValue(), value.intValue());
547: _log.debug("Tree after delete: " + _tree.toString());
548: assertTrue("Tree should be valid after delete", _tree
549: .isValid());
550: assertNull("Value should be deleted for key: "
551: + cur.intValue(), _tree.get(cur.intValue()));
552: }
553: assertEquals("Tree should be empty", 0, _tree.size());
554: }
555:
556: public void testInsertAndDeleteRandomWithReload() throws Exception {
557: Map tests = new HashMap();
558: //Do inserts
559: int max = _max * 10;
560: for (int i = 0; i < max; i++) {
561: Integer key = new Integer(_random.nextInt());
562: Integer value = key;
563: if (!tests.containsKey(key)) {
564: tests.put(key, value);
565: _log.debug("Inserting key " + key);
566: _tree.insert(key.intValue(), value.intValue());
567: _log.debug(_tree.toString());
568: assertTrue("Tree should be valid after insert", _tree
569: .isValid());
570: assertEquals("Should get value back as inserting",
571: value, _tree.get(key.intValue()));
572: }
573: }
574: assertEquals("Should have " + max + " insertions", max, tests
575: .keySet().size());
576:
577: _tree.save(getDbdir());
578:
579: _tree = new IntBTree(getDbdir(), "idx", _deg);
580: //Do deletes
581: Iterator i = tests.keySet().iterator();
582: while (i.hasNext()) {
583: Integer cur = (Integer) i.next();
584: Integer val = (Integer) tests.get(cur);
585: assertEquals("Should get value back", val, _tree.get(cur
586: .intValue()));
587: _log.debug("Deleting key " + cur);
588: _log.debug("Tree before delete: " + _tree.toString());
589: _tree.delete(cur.intValue(), val.intValue());
590: _log.debug("Tree after delete: " + _tree.toString());
591: assertNull("Value should be deleted for key: "
592: + cur.intValue(), _tree.get(cur.intValue()));
593: }
594:
595: _tree.save(getDbdir());
596:
597: _tree = new IntBTree(getDbdir(), "idx", _deg);
598: assertEquals("Tree should be empty", 0, _tree.size());
599: }
600:
601: public void testGetAllTo() throws Exception {
602: testInsertAndRetrieveMany();
603:
604: int topNum = 23;
605: IntIterator iter = _tree.getAllTo(topNum);
606: for (int i = 0; i < topNum; i++) {
607: assertTrue("Iterator should have another value", iter
608: .hasNext());
609: Integer val = new Integer(iter.next());
610: _log.debug("Iterator Value: " + val);
611: assertEquals("Should get the value back for " + i,
612: new Integer(_max - i), val);
613: }
614: }
615:
616: public void testChangeId() throws Exception {
617: testInsertAndRetrieveMany();
618:
619: int key = 18;
620: int oldId = (_tree.get(key)).intValue();
621: _tree.replaceId(key, oldId, oldId + 1000);
622: assertEquals("Should get new id back for " + key, oldId + 1000,
623: (_tree.get(key)).intValue());
624: }
625:
626: public void testChangeIdIdentical() throws Exception {
627: testInsertAndRetrieveManyIdentical();
628:
629: int key = 3;
630: IntList oldIdList = new ArrayIntList();
631: IntIterator iter = null;
632: {
633: // copy the old ids to a new list since _tree.replaceId will change the list
634: IntList ids = new ArrayIntList();
635: for (IntIterator tocopy = _tree.getAll(key); tocopy
636: .hasNext();) {
637: ids.add(tocopy.next());
638: }
639: iter = ids.iterator();
640: }
641: for (int i = 0; iter.hasNext(); i++) {
642: int oldId = iter.next();
643: oldIdList.add(oldId);
644: if ((i % 2) == 0) {
645: _tree.replaceId(key, oldId, oldId + 1000);
646: }
647: }
648:
649: {
650: // copy the old ids to a new list since _tree.replaceId will change the list
651: IntList ids = new ArrayIntList();
652: for (IntIterator tocopy = _tree.getAll(key); tocopy
653: .hasNext();) {
654: ids.add(tocopy.next());
655: }
656: iter = ids.iterator();
657: }
658: for (int i = 0; iter.hasNext(); i++) {
659: int newId = iter.next();
660: int oldId = oldIdList.get(i);
661: if ((i % 2) == 0) {
662: assertEquals("Should get new id back for " + key,
663: oldId + 1000, newId);
664: } else {
665: assertEquals("Should get old id back for " + key,
666: oldId, newId);
667: }
668: }
669: }
670: }
|