KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > je > EnvironmentTest


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002,2006 Oracle. All rights reserved.
5  *
6  * $Id: EnvironmentTest.java,v 1.186 2006/12/05 15:56:59 linda Exp $
7  */

8
9 package com.sleepycat.je;
10
11 import java.io.File JavaDoc;
12 import java.io.IOException JavaDoc;
13 import java.util.HashSet JavaDoc;
14 import java.util.List JavaDoc;
15 import java.util.Set JavaDoc;
16
17 import junit.framework.TestCase;
18
19 import com.sleepycat.je.config.ConfigParam;
20 import com.sleepycat.je.config.EnvironmentParams;
21 import com.sleepycat.je.dbi.DatabaseImpl;
22 import com.sleepycat.je.dbi.EnvConfigObserver;
23 import com.sleepycat.je.dbi.EnvironmentImpl;
24 import com.sleepycat.je.dbi.DbConfigManager;
25 import com.sleepycat.je.dbi.MemoryBudget;
26 import com.sleepycat.je.txn.LockInfo;
27 import com.sleepycat.je.util.StringDbt;
28 import com.sleepycat.je.util.TestUtils;
29 import com.sleepycat.je.utilint.DaemonRunner;
30 import com.sleepycat.je.utilint.DbLsn;
31
32 public class EnvironmentTest extends TestCase {
33
34     private Environment env1;
35     private Environment env2;
36     private Environment env3;
37     private File JavaDoc envHome;
38
39     public EnvironmentTest() {
40         envHome = new File JavaDoc(System.getProperty(TestUtils.DEST_DIR));
41     }
42
43     public void setUp()
44         throws IOException JavaDoc {
45
46         TestUtils.removeLogFiles("Setup", envHome, false);
47     }
48     
49     public void tearDown()
50         throws Exception JavaDoc {
51
52         /*
53      * Close down environments in case the unit test failed so that the log
54      * files can be removed.
55          */

56         try {
57             if (env1 != null) {
58                 env1.close();
59                 env1 = null;
60             }
61         } catch (DatabaseException e) {
62             /* ok, the test closed it */
63         }
64         try {
65             if (env2 != null) {
66                 env2.close();
67                 env2 = null;
68             }
69         } catch (DatabaseException e) {
70             /* ok, the test closed it */
71         }
72         try {
73             if (env3 != null) {
74                 env3.close();
75                 env3 = null;
76             }
77         } catch (DatabaseException e) {
78             /* ok, the test closed it */
79         }
80
81         TestUtils.removeLogFiles("TearDown", envHome, false);
82     }
83
84     /**
85      * Test open and close of an environment.
86      */

87     public void testBasic()
88         throws Throwable JavaDoc {
89
90         try {
91             assertEquals("Checking version", "3.2.13",
92                          JEVersion.CURRENT_VERSION.getVersionString());
93
94             EnvironmentConfig envConfig = TestUtils.initEnvConfig();
95             envConfig.setTransactional(true);
96             envConfig.setCacheSize(MemoryBudget.MIN_MAX_MEMORY_SIZE);
97             /* Don't track detail with a tiny cache size. */
98             envConfig.setConfigParam
99                 (EnvironmentParams.CLEANER_TRACK_DETAIL.getName(), "false");
100             envConfig.setConfigParam
101         (EnvironmentParams.NODE_MAX.getName(), "6");
102             envConfig.setConfigParam
103         (EnvironmentParams.LOG_MEM_SIZE.getName(),
104          EnvironmentParams.LOG_MEM_SIZE_MIN_STRING);
105             envConfig.setConfigParam
106         (EnvironmentParams.NUM_LOG_BUFFERS.getName(), "2");
107             envConfig.setAllowCreate(true);
108             env1 = new Environment(envHome, envConfig);
109
110             env1.close();
111
112             /* Try to open and close again, now that the environment exists. */
113             envConfig.setAllowCreate(false);
114             env1 = new Environment(envHome, envConfig);
115             env1.close();
116         } catch (Throwable JavaDoc t) {
117             t.printStackTrace();
118             throw t;
119         }
120     }
121
122     /**
123      * Test environment reference counting.
124      */

125     public void testReferenceCounting()
126         throws Throwable JavaDoc {
127
128         try {
129
130             /* Create two environment handles on the same environment. */
131             EnvironmentConfig envConfig = TestUtils.initEnvConfig();
132             envConfig.setTransactional(true);
133             envConfig.setCacheSize(MemoryBudget.MIN_MAX_MEMORY_SIZE);
134             /* Don't track detail with a tiny cache size. */
135             envConfig.setConfigParam
136                 (EnvironmentParams.CLEANER_TRACK_DETAIL.getName(), "false");
137             envConfig.setConfigParam(EnvironmentParams.NODE_MAX.getName(),
138                                      "6");
139             envConfig.setConfigParam
140         (EnvironmentParams.LOG_MEM_SIZE.getName(),
141          EnvironmentParams.LOG_MEM_SIZE_MIN_STRING);
142             envConfig.setConfigParam
143         (EnvironmentParams.NUM_LOG_BUFFERS.getName(), "2");
144             envConfig.setAllowCreate(true);
145             env1 = new Environment(envHome, envConfig);
146             envConfig.setAllowCreate(false);
147             env2 = new Environment(envHome, envConfig);
148
149             assertEquals("DbEnvironments should be equal",
150                          env1.getEnvironmentImpl(),
151                          env2.getEnvironmentImpl());
152
153             /* Try to close one of them twice */
154             env1.close();
155             try {
156                 env1.close();
157                 fail("Didn't catch DatabaseException");
158             } catch (DatabaseException DENOE) {
159             }
160
161             /*
162          * Close both, open a third handle, should get a new
163          * EnvironmentImpl.
164              */

165             EnvironmentImpl dbenv1 = env1.getEnvironmentImpl();
166             env2.close();
167             env1 = new Environment(envHome, envConfig);
168             assertTrue("EnvironmentImpl did not change",
169                        dbenv1 != env1.getEnvironmentImpl());
170             try {
171                 env2.close();
172                 fail("Didn't catch DatabaseException");
173             } catch (DatabaseException DENOE) {
174             }
175             env1.close();
176         } catch (Throwable JavaDoc t) {
177             t.printStackTrace();
178             throw t;
179         }
180     }
181
182     public void testTransactional()
183         throws Throwable JavaDoc {
184
185         try {
186             EnvironmentConfig envConfig = TestUtils.initEnvConfig();
187             envConfig.setAllowCreate(true);
188             env1 = new Environment(envHome, envConfig);
189
190             try {
191                 env1.beginTransaction(null, null);
192                 fail("should have thrown exception for non transactional "+
193                      " environment");
194             } catch (DatabaseException DBE) {
195             }
196
197             String JavaDoc databaseName = "simpleDb";
198             DatabaseConfig dbConfig = new DatabaseConfig();
199             dbConfig.setAllowCreate(true);
200             dbConfig.setTransactional(true);
201             try {
202                 env1.openDatabase(null, databaseName, dbConfig);
203                 fail("expected DatabaseException since Environment not " +
204                      "transactional");
205             } catch (DatabaseException DBE) {
206             }
207
208             env1.close();
209         } catch (Throwable JavaDoc t) {
210             t.printStackTrace();
211             throw t;
212         }
213     }
214
215     public void testReadOnly()
216         throws Throwable JavaDoc {
217
218         try {
219             EnvironmentConfig envConfig = TestUtils.initEnvConfig();
220             envConfig.setReadOnly(true);
221             envConfig.setAllowCreate(true);
222             env1 = new Environment(envHome, envConfig);
223
224             DatabaseConfig dbConfig = new DatabaseConfig();
225             dbConfig.setAllowCreate(true);
226             dbConfig.setTransactional(true);
227             String JavaDoc databaseName = "simpleDb";
228             try {
229                 env1.openDatabase(null, databaseName, dbConfig);
230                 fail("expected DatabaseException since Environment is " +
231                      "readonly");
232             } catch (DatabaseException DBE) {
233                 // expected.
234
}
235
236             env1.close();
237         } catch (Throwable JavaDoc t) {
238             t.printStackTrace();
239             throw t;
240         }
241     }
242
243     /*
244      * Tests memOnly mode with a home dir that does not exist. [#15255]
245      */

246     public void testMemOnly()
247         throws Throwable JavaDoc {
248
249         EnvironmentConfig envConfig = TestUtils.initEnvConfig();
250         envConfig.setAllowCreate(true);
251         envConfig.setTransactional(true);
252         envConfig.setConfigParam
253             (EnvironmentParams.LOG_MEMORY_ONLY.getName(), "true");
254
255         File JavaDoc noHome = new File JavaDoc("fileDoesNotExist");
256         assertTrue(!noHome.exists());
257         env1 = new Environment(noHome, envConfig);
258
259         DatabaseConfig dbConfig = new DatabaseConfig();
260         dbConfig.setAllowCreate(true);
261         dbConfig.setTransactional(true);
262         Database db = env1.openDatabase(null, "foo", dbConfig);
263
264         Transaction txn = env1.beginTransaction(null, null);
265         Cursor cursor = db.openCursor(txn, null);
266         doSimpleCursorPutAndDelete(cursor, false);
267         cursor.close();
268         txn.commit();
269         db.close();
270
271         env1.close();
272         assertTrue(!noHome.exists());
273     }
274
275     /**
276      * Tests that opening an environment after a clean close does not add to
277      * the log, but that we do initialize the LastFirstActiveLSN.
278      */

279     public void testOpenWithoutCheckpoint()
280         throws Throwable JavaDoc {
281
282         /* Open, close, open. */
283         EnvironmentConfig envConfig = TestUtils.initEnvConfig();
284         envConfig.setAllowCreate(true);
285         env1 = new Environment(envHome, envConfig);
286         env1.close();
287         env1 = new Environment(envHome, null);
288
289         /* Check that no checkpoint was performed. */
290         EnvironmentStats stats = env1.getStats(null);
291         assertEquals(0, stats.getNCheckpoints());
292
293         /* Check that the FirstActiveLSN is available for the cleaner. */
294         long lsn =
295             env1.getEnvironmentImpl().getCheckpointer().getFirstActiveLsn();
296         assertTrue(DbLsn.compareTo(lsn, DbLsn.makeLsn(0, 0)) > 0);
297
298         env1.close();
299         env1 = null;
300     }
301
302     /**
303      * Test environment configuration.
304      */

305     public void testConfig()
306         throws Throwable JavaDoc {
307
308         /* This tests assumes these props are immutable. */
309         assertTrue(!isMutableConfig("je.lock.timeout"));
310         assertTrue(!isMutableConfig("je.env.isReadOnly"));
311
312         try {
313
314             /*
315              * Make sure that the environment keeps its own copy of the
316              * configuration object.
317              */

318             EnvironmentConfig envConfig = TestUtils.initEnvConfig();
319             envConfig.setReadOnly(true);
320             envConfig.setAllowCreate(true);
321             envConfig.setLockTimeout(7777);
322             env1 = new Environment(envHome, envConfig);
323
324             /*
325              * Change the environment config object, make sure the
326              * environment cloned a copy when it was opened.
327              */

328             envConfig.setReadOnly(false);
329             EnvironmentConfig retrievedConfig1 = env1.getConfig();
330             assertTrue(envConfig != retrievedConfig1);
331             assertEquals(true, retrievedConfig1.getReadOnly());
332             assertEquals(true, retrievedConfig1.getAllowCreate());
333             assertEquals(7777, retrievedConfig1.getLockTimeout());
334             
335             /*
336              * Make sure that the environment returns a cloned config
337              * object when you call Environment.getConfig.
338              */

339             retrievedConfig1.setReadOnly(false);
340             EnvironmentConfig retrievedConfig2 = env1.getConfig();
341             assertEquals(true, retrievedConfig2.getReadOnly());
342             assertTrue(retrievedConfig1 != retrievedConfig2);
343
344             /*
345              * Open a second environment handle, check that it's attributes
346              * are available.
347              */

348             env2 = new Environment(envHome, null);
349             EnvironmentConfig retrievedConfig3 = env2.getConfig();
350             assertEquals(true, retrievedConfig3.getReadOnly());
351             assertEquals(7777, retrievedConfig3.getLockTimeout());
352
353             /*
354              * Open an environment handle on an existing environment with
355              * mismatching config params.
356              */

357             try {
358                 new Environment(envHome, TestUtils.initEnvConfig());
359                 fail("Shouldn't open, config param has wrong number of params");
360             } catch (IllegalArgumentException JavaDoc e) {
361                 /* expected */
362             }
363
364             try {
365                 envConfig.setLockTimeout(8888);
366                 new Environment(envHome, envConfig);
367                 fail("Shouldn't open, cache size doesn't match");
368             } catch (IllegalArgumentException JavaDoc e) {
369                 /* expected */
370             }
371             
372             /*
373              * Ditto for the mutable attributes.
374              */

375             EnvironmentMutableConfig mutableConfig =
376                 new EnvironmentMutableConfig();
377             mutableConfig.setTxnNoSync(true);
378             env1.setMutableConfig(mutableConfig);
379             EnvironmentMutableConfig retrievedMutableConfig1 =
380                 env1.getMutableConfig();
381             assertTrue(mutableConfig != retrievedMutableConfig1);
382             retrievedMutableConfig1.setTxnNoSync(false);
383             EnvironmentMutableConfig retrievedMutableConfig2 =
384                 env1.getMutableConfig();
385             assertEquals(true, retrievedMutableConfig2.getTxnNoSync());
386             assertTrue(retrievedMutableConfig1 != retrievedMutableConfig2);
387
388             /*
389              * Plus check that mutables can be retrieved via the main config.
390              */

391             EnvironmentConfig retrievedConfig4 = env1.getConfig();
392             assertEquals(true, retrievedConfig4.getTxnNoSync());
393             retrievedConfig4 = env2.getConfig();
394             assertEquals(false, retrievedConfig4.getTxnNoSync());
395
396             /*
397              * Check that mutables can be passed to the ctor.
398              */

399             EnvironmentConfig envConfig3 = env2.getConfig();
400             assertEquals(false, envConfig3.getTxnNoSync());
401             envConfig3.setTxnNoSync(true);
402             env3 = new Environment(envHome, envConfig3);
403             EnvironmentMutableConfig retrievedMutableConfig3 =
404                 env3.getMutableConfig();
405             assertNotSame(envConfig3, retrievedMutableConfig3);
406             assertEquals(true, retrievedMutableConfig3.getTxnNoSync());
407         } catch (Throwable JavaDoc t) {
408             t.printStackTrace();
409             throw t;
410         }
411     }
412
413     /**
414      * Test the semantics of env-wide mutable config properties.
415      */

416     public void testMutableConfig()
417         throws DatabaseException {
418
419         /*
420          * Note that during unit testing the shared je.properties is expected
421          * to be empty, so we don't test the application of je.properties here.
422          */

423         final String JavaDoc P1 = EnvironmentParams.ENV_RUN_INCOMPRESSOR.getName();
424         final String JavaDoc P2 = EnvironmentParams.ENV_RUN_CLEANER.getName();
425         final String JavaDoc P3 = EnvironmentParams.ENV_RUN_CHECKPOINTER.getName();
426
427         assertTrue(isMutableConfig(P1));
428         assertTrue(isMutableConfig(P2));
429         assertTrue(isMutableConfig(P3));
430
431         EnvironmentConfig config;
432         EnvironmentMutableConfig mconfig;
433
434         /*
435          * Create env1, first handle.
436          * P1 defaults to true.
437          * P2 is set to true (the default).
438          * P3 is set to false (not the default).
439          */

440         config = TestUtils.initEnvConfig();
441         config.setAllowCreate(true);
442         config.setConfigParam(P2, "true");
443         config.setConfigParam(P3, "false");
444         env1 = new Environment(envHome, config);
445         check3Params(env1, P1, "true", P2, "true", P3, "false");
446
447         MyObserver observer = new MyObserver();
448         env1.getEnvironmentImpl().addConfigObserver(observer);
449         assertEquals(0, observer.testAndReset());
450
451         /*
452          * Open env2, second handle, test that no mutable params can be
453          * overridden.
454          * P1 is set to false.
455          * P2 is set to false.
456          * P3 is set to true.
457          */

458         config = TestUtils.initEnvConfig();
459         config.setConfigParam(P1, "false");
460         config.setConfigParam(P2, "false");
461         config.setConfigParam(P3, "true");
462         env2 = new Environment(envHome, config);
463         assertEquals(0, observer.testAndReset());
464         check3Params(env1, P1, "true", P2, "true", P3, "false");
465
466         /*
467          * Set mutable config explicitly.
468          */

469         mconfig = env2.getMutableConfig();
470         mconfig.setConfigParam(P1, "false");
471         mconfig.setConfigParam(P2, "false");
472         mconfig.setConfigParam(P3, "true");
473         env2.setMutableConfig(mconfig);
474         assertEquals(1, observer.testAndReset());
475         check3Params(env2, P1, "false", P2, "false", P3, "true");
476
477         env1.close();
478         env1 = null;
479         env2.close();
480         env2 = null;
481     }
482
483     /**
484      * Checks that je.txn.deadlockStackTrace is mutable and takes effect.
485      */

486     public void testTxnDeadlockStackTrace()
487         throws DatabaseException {
488
489         String JavaDoc name = EnvironmentParams.TXN_DEADLOCK_STACK_TRACE.getName();
490         assertTrue(isMutableConfig(name));
491
492         EnvironmentConfig config = TestUtils.initEnvConfig();
493         config.setAllowCreate(true);
494         config.setConfigParam(name, "true");
495         env1 = new Environment(envHome, config);
496         assertTrue(LockInfo.getDeadlockStackTrace());
497
498         EnvironmentMutableConfig mconfig = env1.getMutableConfig();
499         mconfig.setConfigParam(name, "false");
500         env1.setMutableConfig(mconfig);
501         assertTrue(!LockInfo.getDeadlockStackTrace());
502
503         mconfig = env1.getMutableConfig();
504         mconfig.setConfigParam(name, "true");
505         env1.setMutableConfig(mconfig);
506         assertTrue(LockInfo.getDeadlockStackTrace());
507
508         env1.close();
509         env1 = null;
510     }
511
512     /**
513      * Checks three config parameter values.
514      */

515     private void check3Params(Environment env,
516                               String JavaDoc p1, String JavaDoc v1,
517                               String JavaDoc p2, String JavaDoc v2,
518                               String JavaDoc p3, String JavaDoc v3)
519         throws DatabaseException {
520
521         EnvironmentConfig config = env.getConfig();
522
523         assertEquals(v1, config.getConfigParam(p1));
524         assertEquals(v2, config.getConfigParam(p2));
525         assertEquals(v3, config.getConfigParam(p3));
526
527         EnvironmentMutableConfig mconfig = env.getMutableConfig();
528
529         assertEquals(v1, mconfig.getConfigParam(p1));
530         assertEquals(v2, mconfig.getConfigParam(p2));
531         assertEquals(v3, mconfig.getConfigParam(p3));
532     }
533
534     /**
535      * Returns whether a config parameter is mutable.
536      */

537     private boolean isMutableConfig(String JavaDoc name) {
538         ConfigParam param = (ConfigParam)
539             EnvironmentParams.SUPPORTED_PARAMS.get(name);
540         assert param != null;
541         return param.isMutable();
542     }
543
544     /**
545      * Observes config changes and remembers how many times it was called.
546      */

547     private static class MyObserver implements EnvConfigObserver {
548
549         private int count = 0;
550         
551         public void envConfigUpdate(DbConfigManager mgr) {
552             count += 1;
553         }
554
555         int testAndReset() {
556             int result = count;
557             count = 0;
558             return result;
559         }
560     }
561
562     /**
563      * Make sure that config param loading follows the right precedence.
564      */

565     public void testParamLoading()
566     throws Throwable JavaDoc {
567
568         File JavaDoc testEnvHome = null;
569         try {
570
571             /*
572              * A je.properties file has been put into
573              * <testdestdir>/propTest/je.properties
574              */

575             StringBuffer JavaDoc testPropsEnv = new StringBuffer JavaDoc();
576             testPropsEnv.append(System.getProperty(TestUtils.DEST_DIR));
577             testPropsEnv.append(File.separatorChar);
578             testPropsEnv.append("propTest");
579             testEnvHome = new File JavaDoc(testPropsEnv.toString());
580             TestUtils.removeLogFiles("testParamLoading start",
581                                      testEnvHome, false);
582
583             /*
584              * Set some configuration params programatically. Do not use
585              * TestUtils.initEnvConfig since we're counting properties.
586              */

587             EnvironmentConfig appConfig = new EnvironmentConfig();
588             appConfig.setConfigParam("je.log.numBuffers", "88");
589             appConfig.setConfigParam
590         ("je.log.totalBufferBytes",
591          EnvironmentParams.LOG_MEM_SIZE_MIN_STRING + 10);
592             appConfig.setAllowCreate(true);
593
594             Environment appEnv = new Environment(testEnvHome, appConfig);
595             EnvironmentConfig envConfig = appEnv.getConfig();
596     
597             assertEquals(3, envConfig.getNumExplicitlySetParams());
598             assertEquals("false",
599                          envConfig.getConfigParam("je.env.recovery"));
600             assertEquals("7001",
601                          envConfig.getConfigParam("je.log.totalBufferBytes"));
602             assertEquals("200",
603                          envConfig.getConfigParam("je.log.numBuffers"));
604             appEnv.close();
605         } catch (Throwable JavaDoc t) {
606             t.printStackTrace();
607             throw t;
608         }
609         finally {
610             TestUtils.removeLogFiles("testParamLoadingEnd",
611                                      testEnvHome, false);
612         }
613     }
614
615     public void testDbRename()
616         throws Throwable JavaDoc {
617
618         try {
619             EnvironmentConfig envConfig = TestUtils.initEnvConfig();
620             envConfig.setTransactional(true);
621             envConfig.setAllowCreate(true);
622             env1 = new Environment(envHome, envConfig);
623
624             String JavaDoc databaseName = "simpleDb";
625             String JavaDoc newDatabaseName = "newSimpleDb";
626
627             /* Try to rename a non-existent db. */
628             try {
629                 env1.renameDatabase(null, databaseName, newDatabaseName);
630                 fail("Rename on non-existent db should fail");
631             } catch (DatabaseException e) {
632                 /* expect exception */
633             }
634
635             /* Now create a test db. */
636             DatabaseConfig dbConfig = new DatabaseConfig();
637             dbConfig.setAllowCreate(true);
638             dbConfig.setTransactional(true);
639             Database exampleDb = env1.openDatabase(null, databaseName,
640                            dbConfig);
641
642             Transaction txn = env1.beginTransaction(null, null);
643             Cursor cursor = exampleDb.openCursor(txn, null);
644             doSimpleCursorPutAndDelete(cursor, false);
645             cursor.close();
646             txn.commit();
647             exampleDb.close();
648
649             dbConfig.setAllowCreate(false);
650             env1.renameDatabase(null, databaseName, newDatabaseName);
651             exampleDb = env1.openDatabase(null, newDatabaseName, dbConfig);
652             cursor = exampleDb.openCursor(null, null);
653             // XXX doSimpleVerification(cursor);
654
cursor.close();
655
656             /* Check debug name. */
657             DatabaseImpl dbImpl = DbInternal.dbGetDatabaseImpl(exampleDb);
658             assertEquals(newDatabaseName, dbImpl.getDebugName());
659             exampleDb.close();
660             try {
661                 exampleDb = env1.openDatabase(null, databaseName, dbConfig);
662                 fail("didn't get db not found exception");
663             } catch (DatabaseException DBE) {
664             }
665             env1.close();
666         } catch (Throwable JavaDoc t) {
667             t.printStackTrace();
668             throw t;
669         }
670     }
671
672     public void testDbRenameCommit()
673         throws Throwable JavaDoc {
674
675         try {
676             EnvironmentConfig envConfig = TestUtils.initEnvConfig();
677             envConfig.setTransactional(true);
678             envConfig.setAllowCreate(true);
679             env1 = new Environment(envHome, envConfig);
680
681             String JavaDoc databaseName = "simpleRenameCommitDb";
682             String JavaDoc newDatabaseName = "newSimpleRenameCommitDb";
683
684             Transaction txn = env1.beginTransaction(null, null);
685             DatabaseConfig dbConfig = new DatabaseConfig();
686             dbConfig.setTransactional(true);
687             dbConfig.setAllowCreate(true);
688             Database exampleDb = env1.openDatabase(txn, databaseName,
689                            dbConfig);
690
691             Cursor cursor = exampleDb.openCursor(txn, null);
692             doSimpleCursorPutAndDelete(cursor, false);
693             cursor.close();
694             exampleDb.close();
695
696             dbConfig.setAllowCreate(false);
697             env1.renameDatabase(txn, databaseName, newDatabaseName);
698             exampleDb = env1.openDatabase(txn, newDatabaseName, dbConfig);
699             cursor = exampleDb.openCursor(txn, null);
700             cursor.close();
701             exampleDb.close();
702             try {
703                 exampleDb = env1.openDatabase(txn, databaseName, dbConfig);
704                 fail("didn't get db not found exception");
705             } catch (DatabaseException DBE) {
706             }
707             txn.commit();
708
709             try {
710                 exampleDb = env1.openDatabase(null, databaseName, null);
711                 fail("didn't catch DatabaseException opening old name");
712             } catch (DatabaseException DBE) {
713             }
714             try {
715                 exampleDb = env1.openDatabase(null, newDatabaseName, null);
716                 exampleDb.close();
717             } catch (DatabaseException DBE) {
718                 fail("caught unexpected exception");
719             }
720
721             env1.close();
722         } catch (Throwable JavaDoc t) {
723             t.printStackTrace();
724             throw t;
725         }
726     }
727
728     public void testDbRenameAbort()
729         throws Throwable JavaDoc {
730
731         try {
732             EnvironmentConfig envConfig = TestUtils.initEnvConfig();
733             envConfig.setTransactional(true);
734             envConfig.setAllowCreate(true);
735             env1 = new Environment(envHome, envConfig);
736
737             /* Create a database. */
738             String JavaDoc databaseName = "simpleRenameAbortDb";
739             String JavaDoc newDatabaseName = "newSimpleRenameAbortDb";
740             Transaction txn = env1.beginTransaction(null, null);
741             DatabaseConfig dbConfig = new DatabaseConfig();
742             dbConfig.setTransactional(true);
743             dbConfig.setAllowCreate(true);
744             Database exampleDb =
745         env1.openDatabase(txn, databaseName, dbConfig);
746
747             /* Put some data in, close the database, commit. */
748             Cursor cursor = exampleDb.openCursor(txn, null);
749             doSimpleCursorPutAndDelete(cursor, false);
750             cursor.close();
751             exampleDb.close();
752             txn.commit();
753
754             /*
755              * Rename under another txn, shouldn't be able to open under the
756              * old name.
757              */

758             txn = env1.beginTransaction(null, null);
759             env1.renameDatabase(txn, databaseName, newDatabaseName);
760             dbConfig.setAllowCreate(false);
761             exampleDb = env1.openDatabase(txn, newDatabaseName, dbConfig);
762             cursor = exampleDb.openCursor(txn, null);
763             // XXX doSimpleVerification(cursor);
764
cursor.close();
765             exampleDb.close();
766             try {
767                 exampleDb = env1.openDatabase(txn, databaseName, dbConfig);
768                 fail("didn't get db not found exception");
769             } catch (DatabaseException DBE) {
770             }
771
772             /*
773              * Abort the rename, should be able to open under the old name with
774              * empty props (DB_CREATE not set)
775              */

776             txn.abort();
777             exampleDb = new Database(env1);
778             try {
779                 exampleDb = env1.openDatabase(null, databaseName, null);
780                 exampleDb.close();
781             } catch (DatabaseException dbe) {
782                 fail("caught DatabaseException opening old name:" +
783                      dbe.getMessage());
784             }
785
786             /* Shouldn't be able to open under the new name. */
787             try {
788                 exampleDb = env1.openDatabase(null, newDatabaseName, null);
789                 fail("didn't catch DatabaseException opening new name");
790             } catch (DatabaseException dbe) {
791             }
792
793             env1.close();
794         } catch (Throwable JavaDoc t) {
795             t.printStackTrace();
796             throw t;
797         }
798     }
799
800     public void testDbRemove()
801         throws Throwable JavaDoc {
802
803         try {
804             /* Set up an environment. */
805             EnvironmentConfig envConfig = TestUtils.initEnvConfig();
806             envConfig.setTransactional(true);
807             envConfig.setAllowCreate(true);
808             env1 = new Environment(envHome, envConfig);
809
810             String JavaDoc databaseName = "simpleDb";
811
812             /* Try to remove a non-existent db */
813             try {
814                 env1.removeDatabase(null, databaseName);
815                 fail("Remove of non-existent db should fail");
816             } catch (DatabaseException e) {
817                 /* expect exception */
818             }
819
820             DatabaseConfig dbConfig = new DatabaseConfig();
821             dbConfig.setTransactional(true);
822             dbConfig.setAllowCreate(true);
823             Database exampleDb =
824         env1.openDatabase(null, databaseName, dbConfig);
825
826             Transaction txn = env1.beginTransaction(null, null);
827             Cursor cursor = exampleDb.openCursor(txn, null);
828             doSimpleCursorPutAndDelete(cursor, false);
829             cursor.close();
830             txn.commit();
831
832             /* Remove should fail because database is open. */
833             try {
834                 env1.removeDatabase(null, databaseName);
835                 fail("didn't get db open exception");
836             } catch (DatabaseException DBE) {
837             }
838             exampleDb.close();
839
840             env1.removeDatabase(null, databaseName);
841
842             /* Remove should fail because database does not exist. */
843             try {
844                 exampleDb = env1.openDatabase(null, databaseName, null);
845                 fail("did not catch db does not exist exception");
846             } catch (DatabaseException DBE) {
847             }
848             env1.close();
849         } catch (Throwable JavaDoc t) {
850             t.printStackTrace();
851             throw t;
852         }
853     }
854
855     public void testDbRemoveCommit()
856         throws Throwable JavaDoc {
857
858         try {
859             /* Set up an environment. */
860             EnvironmentConfig envConfig = TestUtils.initEnvConfig();
861             envConfig.setTransactional(true);
862             envConfig.setAllowCreate(true);
863             env1 = new Environment(envHome, envConfig);
864
865             /* Make a database. */
866             String JavaDoc databaseName = "simpleDb";
867             Transaction txn = env1.beginTransaction(null, null);
868             DatabaseConfig dbConfig = new DatabaseConfig();
869             dbConfig.setTransactional(true);
870             dbConfig.setAllowCreate(true);
871             Database exampleDb =
872         env1.openDatabase(txn, databaseName, dbConfig);
873
874             /* Insert and delete data in it. */
875         Cursor cursor = exampleDb.openCursor(txn, null);
876         doSimpleCursorPutAndDelete(cursor, false);
877         cursor.close();
878
879         /*
880          * Try a remove without closing the open Database handle. Should
881              * get an exception.
882          */

883             try {
884                 env1.removeDatabase(txn, databaseName);
885                 fail("didn't get db open exception");
886             } catch (DatabaseException DBE) {
887             }
888             exampleDb.close();
889
890             /* Do a remove, try to open again. */
891             env1.removeDatabase(txn, databaseName);
892             try {
893                 dbConfig.setAllowCreate(false);
894                 exampleDb = env1.openDatabase(txn, databaseName, dbConfig);
895                 fail("did not catch db does not exist exception");
896             } catch (DatabaseException DBE) {
897             }
898             txn.commit();
899
900             /* Try to open, the db should have been removed. */
901             try {
902                 exampleDb = env1.openDatabase(null, databaseName, null);
903                 fail("did not catch db does not exist exception");
904             } catch (DatabaseException DBE) {
905             }
906             env1.close();
907         } catch (Throwable JavaDoc t) {
908             t.printStackTrace();
909             throw t;
910         }
911     }
912
913     public void testDbRemoveAbort()
914         throws Throwable JavaDoc {
915
916         try {
917             /* Set up an environment. */
918             EnvironmentConfig envConfig = TestUtils.initEnvConfig();
919             envConfig.setTransactional(true);
920             envConfig.setAllowCreate(true);
921             env1 = new Environment(envHome, envConfig);
922
923             /* Create a database, commit. */
924             String JavaDoc databaseName = "simpleDb";
925             Transaction txn = env1.beginTransaction(null, null);
926             DatabaseConfig dbConfig = new DatabaseConfig();
927             dbConfig.setTransactional(true);
928             dbConfig.setAllowCreate(true);
929             Database exampleDb =
930         env1.openDatabase(txn, databaseName, dbConfig);
931             txn.commit();
932
933             /* Start a new txn and put some data in the created db. */
934             txn = env1.beginTransaction(null, null);
935             Cursor cursor = exampleDb.openCursor(txn, null);
936             doSimpleCursorPutAndDelete(cursor, false);
937             cursor.close();
938
939             /*
940          * Try to remove, we should get an exception because the db is
941          * open.
942              */

943             try {
944                 env1.removeDatabase(txn, databaseName);
945                 fail("didn't get db open exception");
946             } catch (DatabaseException DBE) {
947             }
948             exampleDb.close();
949
950         /*
951          * txn can only be aborted at this point since the removeDatabase()
952          * timed out.
953          */

954         txn.abort();
955             txn = env1.beginTransaction(null, null);
956             env1.removeDatabase(txn, databaseName);
957
958             try {
959                 dbConfig.setAllowCreate(false);
960                 exampleDb = env1.openDatabase(txn, databaseName, dbConfig);
961                 fail("did not catch db does not exist exception");
962             } catch (DatabaseException DBE) {
963             }
964
965             /* Abort, should rollback the db remove. */
966             txn.abort();
967
968             try {
969                 DatabaseConfig dbConfig2 = new DatabaseConfig();
970                 dbConfig2.setTransactional(true);
971                 exampleDb = env1.openDatabase(null, databaseName, dbConfig2);
972             } catch (DatabaseException DBE) {
973                 fail("db does not exist anymore after delete/abort");
974             }
975
976             exampleDb.close();
977             env1.close();
978         } catch (Throwable JavaDoc t) {
979             t.printStackTrace();
980             throw t;
981         }
982     }
983
984     /**
985      * Provides general testing of getDatabaseNames. Additionally verifies a
986      * fix for a bug that occurred when the first DB (lowest valued name) was
987      * removed or renamed prior to calling getDatabaseNames. A NPE occurred
988      * in this case if the compressor had not yet deleted the BIN entry for
989      * the removed/renamed name. [#13377]
990      */

991     public void testGetDatabaseNames()
992         throws DatabaseException {
993
994         EnvironmentConfig envConfig = TestUtils.initEnvConfig();
995         envConfig.setAllowCreate(true);
996         envConfig.setConfigParam
997             (EnvironmentParams.ENV_RUN_INCOMPRESSOR.getName(), "false");
998
999         DatabaseConfig dbConfig = new DatabaseConfig();
1000        dbConfig.setAllowCreate(true);
1001
1002        /* Start with no databases. */
1003        Set JavaDoc dbNames = new HashSet JavaDoc();
1004        env1 = new Environment(envHome, envConfig);
1005        checkDbNames(dbNames, env1.getDatabaseNames());
1006
1007        /* Add DB1. */
1008        dbNames.add("DB1");
1009        Database db = env1.openDatabase(null, "DB1", dbConfig);
1010        db.close();
1011        checkDbNames(dbNames, env1.getDatabaseNames());
1012
1013        /* Add DB2. */
1014        dbNames.add("DB2");
1015        db = env1.openDatabase(null, "DB2", dbConfig);
1016        db.close();
1017        checkDbNames(dbNames, env1.getDatabaseNames());
1018
1019        /* Rename DB2 to DB3 (this caused NPE). */
1020        dbNames.remove("DB2");
1021        dbNames.add("DB3");
1022        env1.renameDatabase(null, "DB2", "DB3");
1023        checkDbNames(dbNames, env1.getDatabaseNames());
1024
1025        /* Remove DB1. */
1026        dbNames.remove("DB1");
1027        dbNames.add("DB4");
1028        env1.renameDatabase(null, "DB1", "DB4");
1029        checkDbNames(dbNames, env1.getDatabaseNames());
1030
1031        /* Add DB0. */
1032        dbNames.add("DB0");
1033        db = env1.openDatabase(null, "DB0", dbConfig);
1034        db.close();
1035        checkDbNames(dbNames, env1.getDatabaseNames());
1036
1037        /* Remove DB0 (this caused NPE). */
1038        dbNames.remove("DB0");
1039        env1.removeDatabase(null, "DB0");
1040        checkDbNames(dbNames, env1.getDatabaseNames());
1041
1042        env1.close();
1043        env1 = null;
1044    }
1045
1046    /**
1047     * Checks that the expected set of names equals the list of names returned
1048     * from getDatabaseNames. A list can't be directly compared to a set using
1049     * equals().
1050     */

1051    private void checkDbNames(Set JavaDoc expected, List JavaDoc actual) {
1052        assertEquals(expected.size(), actual.size());
1053        assertEquals(expected, new HashSet JavaDoc(actual));
1054    }
1055
1056    /*
1057     * This little test case can only invoke the compressor, since the evictor,
1058     * cleaner and checkpointer are all governed by utilization metrics and are
1059     * tested elsewhere.
1060     */

1061    public void testDaemonManualInvocation()
1062        throws Throwable JavaDoc {
1063
1064        try {
1065            /* Set up an environment. */
1066            EnvironmentConfig envConfig = TestUtils.initEnvConfig();
1067            envConfig.setTransactional(true);
1068            String JavaDoc testPropVal = "120000000";
1069            envConfig.setConfigParam
1070                (EnvironmentParams.COMPRESSOR_WAKEUP_INTERVAL.getName(),
1071                 testPropVal);
1072            envConfig.setConfigParam
1073                (EnvironmentParams.ENV_RUN_INCOMPRESSOR.getName(), "false");
1074            envConfig.setAllowCreate(true);
1075            envConfig.setConfigParam
1076        (EnvironmentParams.LOG_MEM_SIZE.getName(), "20000");
1077            envConfig.setConfigParam
1078        (EnvironmentParams.NUM_LOG_BUFFERS.getName(), "2");
1079            env1 = new Environment(envHome, envConfig);
1080
1081            String JavaDoc databaseName = "simpleDb";
1082            DatabaseConfig dbConfig = new DatabaseConfig();
1083            dbConfig.setTransactional(true);
1084            dbConfig.setAllowCreate(true);
1085            Database exampleDb =
1086        env1.openDatabase(null, databaseName, dbConfig);
1087
1088            Transaction txn = env1.beginTransaction(null, null);
1089            Cursor cursor = exampleDb.openCursor(txn, null);
1090            doSimpleCursorPutAndDelete(cursor, false);
1091            cursor.close();
1092            txn.commit();
1093            exampleDb.close();
1094            EnvironmentStats envStats = env1.getStats(TestUtils.FAST_STATS);
1095            env1.compress();
1096
1097            envStats = env1.getStats(TestUtils.FAST_STATS);
1098            int compressorTotal =
1099                envStats.getSplitBins() +
1100                envStats.getDbClosedBins() +
1101                envStats.getCursorsBins() +
1102                envStats.getNonEmptyBins() +
1103                envStats.getProcessedBins() +
1104                envStats.getInCompQueueSize();
1105            assertTrue(compressorTotal > 0);
1106
1107            env1.close();
1108        } catch (Throwable JavaDoc t) {
1109            t.printStackTrace();
1110            throw t;
1111        }
1112    }
1113
1114    /**
1115     * Tests that each daemon can be turned on and off dynamically.
1116     */

1117    public void testDaemonRunPause()
1118        throws DatabaseException, InterruptedException JavaDoc {
1119
1120        final String JavaDoc[] runProps = {
1121            EnvironmentParams.ENV_RUN_EVICTOR.getName(),
1122            EnvironmentParams.ENV_RUN_CLEANER.getName(),
1123            EnvironmentParams.ENV_RUN_CHECKPOINTER.getName(),
1124            EnvironmentParams.ENV_RUN_INCOMPRESSOR.getName(),
1125        };
1126
1127        EnvironmentConfig config = TestUtils.initEnvConfig();
1128        config.setAllowCreate(true);
1129
1130        config.setConfigParam
1131            (EnvironmentParams.MAX_MEMORY.getName(),
1132             MemoryBudget.MIN_MAX_MEMORY_SIZE_STRING);
1133        /* Don't track detail with a tiny cache size. */
1134        config.setConfigParam
1135            (EnvironmentParams.CLEANER_TRACK_DETAIL.getName(), "false");
1136        config.setConfigParam
1137            (EnvironmentParams.CLEANER_BYTES_INTERVAL.getName(),
1138             "100");
1139        config.setConfigParam
1140            (EnvironmentParams.CHECKPOINTER_BYTES_INTERVAL.getName(),
1141             "100");
1142        config.setConfigParam
1143            (EnvironmentParams.COMPRESSOR_WAKEUP_INTERVAL.getName(),
1144             "1000000");
1145    config.setConfigParam(EnvironmentParams.LOG_MEM_SIZE.getName(),
1146                  EnvironmentParams.LOG_MEM_SIZE_MIN_STRING);
1147    config.setConfigParam
1148        (EnvironmentParams.NUM_LOG_BUFFERS.getName(), "2");
1149        setBoolConfigParams(config, runProps,
1150                            new boolean[] { false, false, false, false });
1151
1152        env1 = new Environment(envHome, config);
1153        EnvironmentImpl envImpl = env1.getEnvironmentImpl();
1154
1155        final DaemonRunner[] daemons = {
1156            envImpl.getEvictor(),
1157            envImpl.getCleaner(),
1158            envImpl.getCheckpointer(),
1159            envImpl.getINCompressor(),
1160        };
1161
1162        doTestDaemonRunPause(env1, daemons, runProps,
1163                             new boolean[] { false, false, false, false });
1164        doTestDaemonRunPause(env1, daemons, runProps,
1165                             new boolean[] { true, false, false, false });
1166    if (!envImpl.isNoLocking()) {
1167        doTestDaemonRunPause(env1, daemons, runProps,
1168                 new boolean[] { false, true, false, false });
1169    }
1170        doTestDaemonRunPause(env1, daemons, runProps,
1171                             new boolean[] { false, false, true, false });
1172        doTestDaemonRunPause(env1, daemons, runProps,
1173                             new boolean[] { false, false, false, true });
1174        doTestDaemonRunPause(env1, daemons, runProps,
1175                             new boolean[] { false, false, false, false });
1176
1177        env1.close();
1178        env1 = null;
1179    }
1180
1181    /**
1182     * Tests a set of daemon on/off settings.
1183     */

1184    private void doTestDaemonRunPause(Environment env,
1185                      DaemonRunner[] daemons,
1186                                      String JavaDoc[] runProps,
1187                      boolean[] runValues)
1188        throws DatabaseException, InterruptedException JavaDoc {
1189
1190        /* Set daemon run properties. */
1191        EnvironmentMutableConfig config = env.getMutableConfig();
1192        setBoolConfigParams(config, runProps, runValues);
1193        env.setMutableConfig(config);
1194
1195        /* Allow previously running daemons to come to a stop. */
1196        for (int i = 0; i < 10; i += 1) {
1197            Thread.yield();
1198            Thread.sleep(10);
1199        }
1200
1201        /* Get current wakeup counts. */
1202        int[] prevCounts = new int[daemons.length];
1203        for (int i = 0; i < prevCounts.length; i += 1) {
1204            prevCounts[i] = daemons[i].getNWakeupRequests();
1205        }
1206
1207        /* Write some data to wakeup the checkpointer, cleaner and evictor. */
1208        String JavaDoc dbName = "testDaemonRunPause";
1209        DatabaseConfig dbConfig = new DatabaseConfig();
1210        dbConfig.setAllowCreate(true);
1211    dbConfig.setSortedDuplicates(true);
1212        Database db = env1.openDatabase(null, dbName, dbConfig);
1213        Cursor cursor = db.openCursor(null, null);
1214        doSimpleCursorPutAndDelete(cursor, true);
1215        cursor.close();
1216        db.close();
1217
1218        /* Sleep for a while to wakeup the compressor. */
1219        Thread.sleep(1000);
1220
1221        /* Check that the expected daemons were woken. */
1222        for (int i = 0; i < prevCounts.length; i += 1) {
1223            int currNWakeups = daemons[i].getNWakeupRequests();
1224            boolean woken = prevCounts[i] < currNWakeups;
1225            assertEquals(daemons[i].getClass().getName() +
1226                         " prevNWakeups=" + prevCounts[i] +
1227                         " currNWakeups=" + currNWakeups,
1228                         runValues[i], woken);
1229        }
1230    }
1231
1232    private void setBoolConfigParams(EnvironmentMutableConfig config,
1233                                     String JavaDoc[] names,
1234                     boolean[] values) {
1235        for (int i = 0; i < names.length; i += 1) {
1236            config.setConfigParam(names[i],
1237                                  Boolean.valueOf(values[i]).toString());
1238        }
1239    }
1240
1241    public void testClose()
1242        throws Throwable JavaDoc {
1243
1244        try {
1245            EnvironmentConfig envConfig = TestUtils.initEnvConfig();
1246            envConfig.setTransactional(true);
1247            envConfig.setAllowCreate(true);
1248            env1 = new Environment(envHome, envConfig);
1249
1250            env1.close();
1251            try {
1252                env1.close();
1253                fail("Didn't catch DatabaseException");
1254            } catch (DatabaseException DENOE) {
1255            }
1256
1257            envConfig.setAllowCreate(false);
1258            env1 = new Environment(envHome, envConfig);
1259            
1260           /* Create a transaction to prevent the close from succeeding */
1261            env1.beginTransaction(null, null);
1262        try {
1263        env1.close();
1264        fail("Didn't catch DatabaseException for open transactions");
1265        } catch (DatabaseException DBE) {
1266        }
1267
1268        try {
1269        env1.close();
1270        fail("Didn't catch DatabaseException already closed env");
1271        } catch (DatabaseException DBE) {
1272        }
1273
1274            env1 = new Environment(envHome, envConfig);
1275
1276            String JavaDoc databaseName = "simpleDb";
1277            DatabaseConfig dbConfig = new DatabaseConfig();
1278            dbConfig.setTransactional(true);
1279            dbConfig.setAllowCreate(true);
1280            Database exampleDb =
1281        env1.openDatabase(null, databaseName, dbConfig);
1282        try {
1283        env1.close();
1284        fail("Didn't catch DatabaseException for open dbs");
1285        } catch (DatabaseException DBE) {
1286        }
1287        try {
1288        env1.close();
1289        fail("Didn't catch DatabaseException already closed env");
1290        } catch (DatabaseException DBE) {
1291        }
1292
1293        } catch (Throwable JavaDoc t) {
1294            t.printStackTrace();
1295            throw t;
1296        }
1297    }
1298
1299    protected String JavaDoc[] simpleKeyStrings = {
1300        "foo", "bar", "baz", "aaa", "fubar",
1301        "foobar", "quux", "mumble", "froboy" };
1302
1303    protected String JavaDoc[] simpleDataStrings = {
1304        "one", "two", "three", "four", "five",
1305        "six", "seven", "eight", "nine" };
1306
1307    protected void doSimpleCursorPutAndDelete(Cursor cursor, boolean extras)
1308        throws DatabaseException {
1309
1310        StringDbt foundKey = new StringDbt();
1311        StringDbt foundData = new StringDbt();
1312
1313        for (int i = 0; i < simpleKeyStrings.length; i++) {
1314            foundKey.setString(simpleKeyStrings[i]);
1315            foundData.setString(simpleDataStrings[i]);
1316            if (cursor.putNoOverwrite(foundKey, foundData) !=
1317                OperationStatus.SUCCESS) {
1318                throw new DatabaseException("non-0 return");
1319            }
1320        /* Need to write some extra out to force eviction to run. */
1321        if (extras) {
1322        for (int j = 0; j < 500; j++) {
1323            foundData.setString(Integer.toString(j));
1324            OperationStatus status =
1325            cursor.put(foundKey, foundData);
1326            if (status != OperationStatus.SUCCESS) {
1327            throw new DatabaseException("non-0 return " + status);
1328            }
1329        }
1330        }
1331        }
1332
1333        OperationStatus status =
1334            cursor.getFirst(foundKey, foundData, LockMode.DEFAULT);
1335
1336        while (status == OperationStatus.SUCCESS) {
1337            cursor.delete();
1338            status = cursor.getNext(foundKey, foundData, LockMode.DEFAULT);
1339        }
1340    }
1341
1342    protected void doSimpleVerification(Cursor cursor)
1343        throws DatabaseException {
1344
1345        StringDbt foundKey = new StringDbt();
1346        StringDbt foundData = new StringDbt();
1347
1348        int count = 0;
1349        OperationStatus status = cursor.getFirst(foundKey, foundData,
1350                                                 LockMode.DEFAULT);
1351
1352        while (status == OperationStatus.SUCCESS) {
1353            count++;
1354            status = cursor.getNext(foundKey, foundData, LockMode.DEFAULT);
1355        }
1356        assertEquals(simpleKeyStrings.length, count);
1357    }
1358}
1359
Popular Tags