diff options
| author | Lorry <lorry@roadtrain.codethink.co.uk> | 2012-07-20 20:00:05 +0100 |
|---|---|---|
| committer | Lorry <lorry@roadtrain.codethink.co.uk> | 2012-07-20 20:00:05 +0100 |
| commit | 3ef782d3745ea8f25a3151561a3cfb882190210e (patch) | |
| tree | 86b9c2f5fde051dd0bced99b3fc9f5a3ba08db69 /test/java/junit/src/com | |
| download | berkeleydb-3ef782d3745ea8f25a3151561a3cfb882190210e.tar.gz | |
Tarball conversion
Diffstat (limited to 'test/java/junit/src/com')
19 files changed, 4092 insertions, 0 deletions
diff --git a/test/java/junit/src/com/sleepycat/db/test/AppendRecnoTest.java b/test/java/junit/src/com/sleepycat/db/test/AppendRecnoTest.java new file mode 100644 index 00000000..f3c8b307 --- /dev/null +++ b/test/java/junit/src/com/sleepycat/db/test/AppendRecnoTest.java @@ -0,0 +1,209 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. + * + */ + +/* + * Alexg 23-4-06 + * Based on scr016 TestAppendRecno test application. + */ + +package com.sleepycat.db.test; + +import org.junit.Before; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.FileNotFoundException; +import com.sleepycat.db.*; + +import com.sleepycat.db.DatabaseException; + +import com.sleepycat.db.test.TestUtils; + +public class AppendRecnoTest implements RecordNumberAppender { + + public static final String RECNOTEST_DBNAME = "appendrecnotest.db"; + + public static final String[] EXPECTED_ENTRIES = { "data0_xyz", "data1_xy", "ata4_xyz", "ata5_xy", + "abc", "", "data9_xyz" }; + + int callback_count = 0; + boolean callback_throws = false; + + @BeforeClass public static void ClassInit() { + TestUtils.loadConfig(null); + TestUtils.check_file_removed(TestUtils.getDBFileName(RECNOTEST_DBNAME), true, true); + } + + @AfterClass public static void ClassShutdown() { + TestUtils.check_file_removed(TestUtils.getDBFileName(RECNOTEST_DBNAME), true, true); + } + + @Before public void PerTestInit() + throws Exception { + TestUtils.removeall(true, false, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(RECNOTEST_DBNAME)); + } + + @After public void PerTestShutdown() + throws Exception { + } + + /* + * Test creating a new database. + */ + @Test public void test1() + throws DatabaseException, FileNotFoundException + { + DatabaseConfig dbConfig = new DatabaseConfig(); + dbConfig.setErrorStream(TestUtils.getErrorStream()); + dbConfig.setErrorPrefix("AppendRecnoTest"); + dbConfig.setType(DatabaseType.RECNO); + dbConfig.setPageSize(1024); + dbConfig.setAllowCreate(true); + dbConfig.setRecordNumberAppender(this); + + Database db = new Database(TestUtils.getDBFileName(RECNOTEST_DBNAME), null, dbConfig); + + for (int i=0; i<10; i++) { + TestUtils.DEBUGOUT("\n*** Iteration " + i ); + boolean gotExcept = false; + try { + RecnoEntry key = new RecnoEntry(77+i); + DatabaseEntry data = new DatabaseEntry((new String("data" + i + "_xyz")).getBytes()); + db.append(null, key, data); + } + catch (DatabaseException dbe) { + gotExcept = true; + // Can be expected since testing throwing from the appendRecordNumber callback. + TestUtils.DEBUGOUT("dbe: " + dbe); + } catch (ArrayIndexOutOfBoundsException e) { + gotExcept = true; + TestUtils.DEBUGOUT("ArrayIndex: " + e); + } + if((gotExcept && callback_throws == false ) || (!gotExcept && callback_throws == true)) + TestUtils.DEBUGOUT(3, "appendRecordNumber callback exception or non-exception condition dealt with incorrectly. Case " + callback_count); + } + + Cursor dbcp = db.openCursor(null, CursorConfig.DEFAULT); + + // Walk through the table, validating the key/data pairs. + RecnoEntry readkey = new RecnoEntry(); + DatabaseEntry readdata = new DatabaseEntry(); + TestUtils.DEBUGOUT("Dbc.get"); + + int itemcount = 0; + while (dbcp.getNext(readkey, readdata, LockMode.DEFAULT) == OperationStatus.SUCCESS) { + String gotString = new String(readdata.getData(), readdata.getOffset(), readdata.getSize()); + TestUtils.DEBUGOUT(1, readkey.getRecno() + " : " + gotString); + + if(readkey.getRecno() != ++itemcount) + TestUtils.DEBUGOUT(3, "Recno iteration out of order. key: " + readkey.getRecno() + " item: " + itemcount); + + if(itemcount > EXPECTED_ENTRIES.length) + TestUtils.ERR("More entries in recno DB than expected."); + + + if(gotString.compareTo(EXPECTED_ENTRIES[itemcount-1]) != 0) + TestUtils.DEBUGOUT(3, "Recno - stored data mismatch. Expected: " + EXPECTED_ENTRIES[itemcount-1] + " received: " + gotString); + } + + dbcp.close(); + db.close(false); + + } + + public void appendRecordNumber(Database db, DatabaseEntry data, int recno) + throws DatabaseException + { + callback_throws = false; + TestUtils.DEBUGOUT("AppendRecnoTest::appendRecordNumber. data " + new String(data.getData()) + " recno: " + recno); + + switch (callback_count++) { + case 0: + // nothing + break; + + case 1: + data.setSize(data.getSize() - 1); + break; + + case 2: + // Should result in an error. + callback_throws = true; + TestUtils.DEBUGOUT("throwing..."); + throw new DatabaseException("appendRecordNumber thrown"); + //not reached + + case 3: + // Should result in an error (size unchanged). + callback_throws = true; + data.setOffset(1); + break; + + case 4: + data.setOffset(1); + data.setSize(data.getSize() - 1); + break; + + case 5: + data.setOffset(1); + data.setSize(data.getSize() - 2); + break; + + case 6: + data.setData(new String("abc").getBytes()); + data.setSize(3); + break; + + case 7: + // Should result in an error. + callback_throws = true; + data.setData(new String("abc").getBytes()); + data.setSize(4); + break; +// TODO: Broken - does not throw an exception. + case 8: + // TODO: Should this result in an error? + data.setData(null); + break; + + default: + break; + } + } + + static class RecnoEntry extends DatabaseEntry + { + public RecnoEntry() { + super(); + } + + public RecnoEntry(int value) + { + setReuseBuffer(false); + arr = new byte[4]; + setData(arr); // use our local array for data + setRecno(value); + } + + public void setRecno(int value) + { + setRecordNumber(value); + } + + public int getRecno() + { + return getRecordNumber(); + } + byte arr[]; + } // end of RecnoEntry sub-class. + +} diff --git a/test/java/junit/src/com/sleepycat/db/test/AssociateTest.java b/test/java/junit/src/com/sleepycat/db/test/AssociateTest.java new file mode 100644 index 00000000..3cf8b187 --- /dev/null +++ b/test/java/junit/src/com/sleepycat/db/test/AssociateTest.java @@ -0,0 +1,252 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. + * + */ + +/* + * Alexg 23-4-06 + * Based on scr016 TestAssociate test application. + */ + +package com.sleepycat.db.test; + +import org.junit.Before; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.FileNotFoundException; +import com.sleepycat.db.*; + +import com.sleepycat.db.DatabaseException; + +import com.sleepycat.db.test.TestUtils; + +public class AssociateTest { + + public static final String ASSOCTEST_DBNAME = "associatetest.db"; + + public static final String[] DATABASETEST_SAMPLE_DATA = {"abc", "def", "ghi", "JKL", "MNO", "pqrst", "UVW", "y", "Z"}; + + public static Database savedPriDb = null; + public static Database savedSecDb = null; + + int callback_count = 0; + boolean callback_throws = false; + + @BeforeClass public static void ClassInit() { + TestUtils.loadConfig(null); + TestUtils.check_file_removed(TestUtils.getDBFileName(ASSOCTEST_DBNAME), true, true); + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(ASSOCTEST_DBNAME)); + } + + @AfterClass public static void ClassShutdown() { + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(ASSOCTEST_DBNAME)); + } + + @Before public void PerTestInit() + throws Exception { + } + + @After public void PerTestShutdown() + throws Exception { + } + + /* + * Test creating a new database. + */ + @Test public void test1() + throws DatabaseException, FileNotFoundException + { + int i; + EnvironmentConfig envc = new EnvironmentConfig(); + envc.setAllowCreate(true); + envc.setInitializeCache(true); + Environment dbEnv = new Environment(TestUtils.BASETEST_DBFILE, envc); + + DatabaseConfig dbConfig = new DatabaseConfig(); + dbConfig.setErrorStream(TestUtils.getErrorStream()); + dbConfig.setErrorPrefix("AssociateTest"); + dbConfig.setType(DatabaseType.BTREE); + dbConfig.setAllowCreate(true); + + Database priDb = dbEnv.openDatabase(null, ASSOCTEST_DBNAME, null, dbConfig); + + SecondaryConfig secConfig = new SecondaryConfig(); + secConfig.setAllowCreate(true); + secConfig.setType(DatabaseType.BTREE); + secConfig.setSortedDuplicates(true); + secConfig.setKeyCreator(new Capitalize()); + SecondaryDatabase secDb = dbEnv.openSecondaryDatabase(null, ASSOCTEST_DBNAME+"2", null, + priDb, secConfig); + savedPriDb = priDb; + savedSecDb = secDb; + + // Insert records into the database + for(i =0; i < DATABASETEST_SAMPLE_DATA.length; i++) + { + String curdata = DATABASETEST_SAMPLE_DATA[i]; + String reversed = (new StringBuffer(curdata)).reverse().toString(); + + DatabaseEntry key = new DatabaseEntry(curdata.getBytes()); + key.setReuseBuffer(false); + DatabaseEntry data = new DatabaseEntry(reversed.getBytes()); + data.setReuseBuffer(false); + try { + if (priDb.putNoOverwrite(null, key, data) == OperationStatus.KEYEXIST) { + // should not in this - since we control the data. + TestUtils.DEBUGOUT(2, "Key: " + curdata + " already exists\n"); + } + } catch(DatabaseException dbe) { + TestUtils.ERR("Caught DatabaseException: " + dbe); + } + } + + DatabaseEntry readkey = new DatabaseEntry(); + readkey.setReuseBuffer(false); + DatabaseEntry readdata = new DatabaseEntry(); + readdata.setReuseBuffer(false); + Cursor dbcp = priDb.openCursor(null, CursorConfig.DEFAULT); + while (dbcp.getNext(readkey, readdata, LockMode.DEFAULT) == OperationStatus.SUCCESS) { + String keystring = new String(readkey.getData()); + String datastring = new String(readdata.getData()); + String expecteddata = (new StringBuffer(keystring)).reverse().toString(); + + boolean found = false; + for(i = 0; i < DATABASETEST_SAMPLE_DATA.length; i++) + { + if(DATABASETEST_SAMPLE_DATA[i].compareTo(keystring) == 0) + found = true; + } + if(!found) + TestUtils.ERR("Key: " + keystring + " retrieved from DB, but never added!"); + if(datastring.compareTo(expecteddata) != 0) + TestUtils.ERR("Data: " + datastring + " does not match expected data: " + expecteddata); + } + + // Test secondary get functionality. + DatabaseEntry seckey = new DatabaseEntry(); + seckey.setReuseBuffer(false); + DatabaseEntry secpkey = new DatabaseEntry(); + secpkey.setReuseBuffer(false); + DatabaseEntry secdata = new DatabaseEntry(); + secdata.setReuseBuffer(false); + + seckey.setData("BC".getBytes()); + if(secDb.get(null, seckey, secdata, null) == OperationStatus.SUCCESS) + { + TestUtils.DEBUGOUT(2, "seckey: " + new String(seckey.getData()) + " secdata: " + + new String(secdata.getData())); + } else { + TestUtils.ERR("Secondary get of key: " + new String(seckey.getData()) + " did not succeed."); + } + // pget + if(secDb.get(null, seckey, secpkey, secdata, null) == OperationStatus.SUCCESS) + { + TestUtils.DEBUGOUT(2, "seckey: " + new String(seckey.getData()) + " secdata: " + + new String(secdata.getData()) + " pkey: " + new String(secpkey.getData())); + + // ensure that the retrievals are consistent using both primary and secondary keys. + DatabaseEntry tmpdata = new DatabaseEntry(); + priDb.get(null, secpkey, tmpdata, null); + String tmpstr = new String(tmpdata.getData()); + if(tmpstr.compareTo(new String(secdata.getData())) != 0) + TestUtils.ERR("Data retrieved from matching primary secondary keys is not consistent. secdata: " + new String(secdata.getData()) + + " pridata: " + new String(tmpdata.getData())); + } else { + TestUtils.ERR("Secondary pget of key: " + new String(seckey.getData()) + " did not succeed."); + } + seckey.setData("KL".getBytes()); + if(secDb.get(null, seckey, secdata, null) == OperationStatus.SUCCESS) + { + TestUtils.DEBUGOUT(2, "seckey: " + new String(seckey.getData()) + " secdata: " + + new String(secdata.getData())); + } else { + TestUtils.ERR("Secondary get of key: " + new String(seckey.getData()) + " did not succeed."); + } + // pget + if(secDb.get(null, seckey, secpkey, secdata, null) == OperationStatus.SUCCESS) + { + TestUtils.DEBUGOUT(2, "seckey: " + new String(seckey.getData()) + " secdata: " + + new String(secdata.getData()) + " pkey: " + new String(secpkey.getData())); + + // ensure that the retrievals are consistent using both primary and secondary keys. + DatabaseEntry tmpdata = new DatabaseEntry(); + priDb.get(null, secpkey, tmpdata, null); + String tmpstr = new String(tmpdata.getData()); + if(tmpstr.compareTo(new String(secdata.getData())) != 0) + TestUtils.ERR("Data retrieved from matching primary secondary keys is not consistent. secdata: " + new String(secdata.getData()) + + " pridata: " + new String(tmpdata.getData())); + } else { + TestUtils.ERR("Secondary pget of key: " + new String(seckey.getData()) + " did not succeed."); + } + + } + +/************************************************************************************** + ************************************************************************************** + **************************************************************************************/ + /* creates a stupid secondary index as follows: + For an N letter key, we use N-1 letters starting at + position 1. If the new letters are already capitalized, + we return the old array, but with offset set to 1. + If the letters are not capitalized, we create a new, + capitalized array. This is pretty stupid for + an application, but it tests all the paths in the runtime. + */ + public static class Capitalize implements SecondaryKeyCreator + { + public boolean createSecondaryKey(SecondaryDatabase secondary, + DatabaseEntry key, + DatabaseEntry data, + DatabaseEntry result) + throws DatabaseException + { + key.setReuseBuffer(false); + data.setReuseBuffer(false); + result.setReuseBuffer(false); + String which = "unknown db"; + if (savedPriDb.equals(secondary)) { + which = "primary"; + } + else if (savedSecDb.equals(secondary)) { + which = "secondary"; + } + String keystring = new String(key.getData()); + String datastring = new String(data.getData()); + TestUtils.DEBUGOUT(2, "secondaryKeyCreate, Db: " + TestUtils.shownull(secondary) + "(" + which + "), key: " + keystring + ", data: " + datastring); + int len = key.getSize(); + byte[] arr = key.getData(); + boolean capped = true; + + if (len < 1) + throw new DatabaseException("bad key"); + + result.setSize(len - 1); + for (int i=1; capped && i<len; i++) { + if (!Character.isUpperCase((char)arr[i])) + capped = false; + } + if (capped) { + TestUtils.DEBUGOUT(2, " creating key(1): " + new String(arr, 1, len-1)); + result.setData(arr); + result.setOffset(1); + result.setSize(result.getSize() -1); + } + else { + TestUtils.DEBUGOUT(2, " creating key(2): " + (new String(arr)).substring(1). + toUpperCase()); + result.setData((new String(arr)).substring(1). + toUpperCase().getBytes()); + } + return true; + } + } + +} diff --git a/test/java/junit/src/com/sleepycat/db/test/BackupTest.java b/test/java/junit/src/com/sleepycat/db/test/BackupTest.java new file mode 100644 index 00000000..6b41336d --- /dev/null +++ b/test/java/junit/src/com/sleepycat/db/test/BackupTest.java @@ -0,0 +1,222 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. + * + */ + + +package com.sleepycat.db.test; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import com.sleepycat.db.*; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; + +import com.sleepycat.db.test.TestUtils; +import com.sleepycat.bind.tuple.IntegerBinding; + +public class BackupTest { + public static final String BACKUPTEST_DBNAME = "backuptest.db"; + @BeforeClass public static void ClassInit() { + TestUtils.loadConfig(null); + TestUtils.check_file_removed(TestUtils.getDBFileName(BACKUPTEST_DBNAME), true, true); + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(BACKUPTEST_DBNAME)); + } + + @AfterClass public static void ClassShutdown() { + TestUtils.check_file_removed(TestUtils.getDBFileName(BACKUPTEST_DBNAME), true, true); + } + + @Before public void PerTestInit() + throws Exception { + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(BACKUPTEST_DBNAME)); + TestUtils.removeall(true, true, TestUtils.BASETEST_BACKUPDIR, TestUtils.getBackupFileName(BACKUPTEST_DBNAME)); + } + + @After public void PerTestShutdown() + throws Exception { + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(BACKUPTEST_DBNAME)); + TestUtils.removeall(true, true, TestUtils.BASETEST_BACKUPDIR, TestUtils.getBackupFileName(BACKUPTEST_DBNAME)); + } + /* + * Test case implementations. + * To disable a test mark it with @Ignore + * To set a timeout(ms) notate like: @Test(timeout=1000) + * To indicate an expected exception notate like: (expected=Exception) + */ + + @Test public void test1() + throws DatabaseException, FileNotFoundException + { + TestUtils.debug_level = 2; + EnvironmentConfig envc = new EnvironmentConfig(); + envc.setAllowCreate(true); + envc.setInitializeCache(true); + envc.setTransactional(true); + envc.setInitializeLocking(true); + envc.setCacheSize(64 * 1024); + Environment dbEnv = new Environment(TestUtils.BASETEST_DBFILE, envc); + + // Set up a transactional DB. + DatabaseConfig dbConfig = new DatabaseConfig(); + dbConfig.setType(DatabaseType.BTREE); + dbConfig.setAllowCreate(true); + Database db = dbEnv.openDatabase(null, BACKUPTEST_DBNAME, null, dbConfig); + populateDb(db, 1000); + db.close(); + + BackupOptions opt = new BackupOptions(); + opt.setAllowCreate(true); + opt.setExclusiveCreate(true); + dbEnv.backup(TestUtils.BASETEST_BACKUPDIR, opt); + assertTrue(TestUtils.BASETEST_BACKUPFILE.listFiles().length > 0); + + dbEnv.close(); + } + + @Test public void test2() + throws DatabaseException, FileNotFoundException + { + TestUtils.debug_level = 2; + EnvironmentConfig envc = new EnvironmentConfig(); + envc.setAllowCreate(true); + envc.setInitializeCache(true); + envc.setTransactional(true); + envc.setInitializeLocking(true); + envc.setCacheSize(64 * 1024); + Environment dbEnv = new Environment(TestUtils.BASETEST_DBFILE, envc); + + // Set up a transactional DB. + DatabaseConfig dbConfig = new DatabaseConfig(); + dbConfig.setType(DatabaseType.BTREE); + dbConfig.setAllowCreate(true); + Database db = dbEnv.openDatabase(null, BACKUPTEST_DBNAME, null, dbConfig); + populateDb(db, 1000); + db.close(); + + dbEnv.backupDatabase(BACKUPTEST_DBNAME, TestUtils.BASETEST_BACKUPDIR, true); + assertTrue(TestUtils.BASETEST_BACKUPFILE.listFiles().length == 1); + + dbEnv.close(); + } + + @Test public void test3() + throws DatabaseException, FileNotFoundException + { + TestUtils.debug_level = 2; + EnvironmentConfig envc = new EnvironmentConfig(); + envc.setAllowCreate(true); + envc.setInitializeCache(true); + envc.setTransactional(true); + envc.setInitializeLocking(true); + envc.setCacheSize(64 * 1024); + envc.setBackupReadCount(4096); + envc.setBackupReadSleep(1000); + envc.setBackupSize(1024); + envc.setBackupWriteDirect(true); + Environment dbEnv = new Environment(TestUtils.BASETEST_DBFILE, envc); + + // Set up a transactional DB. + DatabaseConfig dbConfig = new DatabaseConfig(); + dbConfig.setType(DatabaseType.BTREE); + dbConfig.setAllowCreate(true); + Database db = dbEnv.openDatabase(null, BACKUPTEST_DBNAME, null, dbConfig); + populateDb(db, 1000); + db.close(); + + dbEnv.backupDatabase(BACKUPTEST_DBNAME, TestUtils.BASETEST_BACKUPDIR, true); + assertTrue(TestUtils.BASETEST_BACKUPFILE.listFiles().length == 1); + + dbEnv.close(); + } + + static class BackupWriter implements BackupHandler { + RandomAccessFile f; + + public int open(String target, String dbname) { + try { + String path = target + '/' + dbname; + f = new RandomAccessFile(path, "rwd"); + } catch (FileNotFoundException fnfe) { + return 1; + } + return 0; + } + + public int write(long pos, byte[] buf, int off, int len) { + try { + f.seek(pos); + f.write(buf, off, len); + } catch (IOException ioe) { + return 1; + } + return 0; + } + + public int close(String dbname) { + try { + f.close(); + } catch (IOException ioe) { + return 1; + } + return 0; + } + } + + @Test public void test4() + throws DatabaseException, FileNotFoundException + { + TestUtils.debug_level = 2; + BackupWriter bw = new BackupTest.BackupWriter(); + + EnvironmentConfig envc = new EnvironmentConfig(); + envc.setAllowCreate(true); + envc.setInitializeCache(true); + envc.setTransactional(true); + envc.setInitializeLocking(true); + envc.setCacheSize(64 * 1024); + envc.setBackupHandler(bw); + Environment dbEnv = new Environment(TestUtils.BASETEST_DBFILE, envc); + + // Set up a transactional DB. + DatabaseConfig dbConfig = new DatabaseConfig(); + dbConfig.setType(DatabaseType.BTREE); + dbConfig.setAllowCreate(true); + Database db = dbEnv.openDatabase(null, BACKUPTEST_DBNAME, null, dbConfig); + populateDb(db, 1000); + db.close(); + + BackupOptions opt = new BackupOptions(); + opt.setAllowCreate(true); + opt.setExclusiveCreate(true); + dbEnv.backup(TestUtils.BASETEST_BACKUPDIR, opt); + assertTrue(TestUtils.BASETEST_BACKUPFILE.listFiles().length > 0); + + dbEnv.close(); + } + + public void populateDb(Database db, int nrecs) + throws DatabaseException { + byte[] arr = new byte[1024]; + DatabaseEntry key, data; + + data = new DatabaseEntry(arr); + key = new DatabaseEntry(); + for (int i = 0; i < nrecs; i++) { + IntegerBinding.intToEntry(i, key); + db.putNoOverwrite(null, key, data); + } + } +} diff --git a/test/java/junit/src/com/sleepycat/db/test/CallbackTest.java b/test/java/junit/src/com/sleepycat/db/test/CallbackTest.java new file mode 100644 index 00000000..2b65f79b --- /dev/null +++ b/test/java/junit/src/com/sleepycat/db/test/CallbackTest.java @@ -0,0 +1,159 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. + * + */ + +/* + * Alexg 23-4-06 + * Based on scr016 TestCallback test application. + * + * Simple tests for DbErrorHandler, DbFeedbackHandler, DbPanicHandler + */ + +package com.sleepycat.db.test; + +import org.junit.Before; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.FileNotFoundException; +import com.sleepycat.db.*; + +import com.sleepycat.db.DatabaseException; + +import com.sleepycat.db.test.TestUtils; + +public class CallbackTest + implements FeedbackHandler, PanicHandler, ErrorHandler { + + public static final String CALLBACKTEST_DBNAME = "callbacktest.db"; + + int callback_count = 0; + boolean callback_throws = false; + + @BeforeClass public static void ClassInit() { + TestUtils.loadConfig(null); + TestUtils.check_file_removed(TestUtils.getDBFileName(CALLBACKTEST_DBNAME), true, true); + } + + @AfterClass public static void ClassShutdown() { + TestUtils.check_file_removed(TestUtils.getDBFileName(CALLBACKTEST_DBNAME), true, true); + } + + @Before public void PerTestInit() + throws Exception { + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(CALLBACKTEST_DBNAME)); + } + + @After public void PerTestShutdown() + throws Exception { + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(CALLBACKTEST_DBNAME)); + } + + /* + * Test creating a new database. + */ + @Test public void test1() + throws DatabaseException, FileNotFoundException + { + TestUtils.debug_level = 2; + EnvironmentConfig envc = new EnvironmentConfig(); + envc.setAllowCreate(true); + envc.setInitializeCache(true); + envc.setTransactional(true); + envc.setInitializeLocking(true); + envc.setCacheSize(64 * 1024); + envc.setFeedbackHandler(this); + envc.setPanicHandler(this); + envc.setErrorHandler(this); + Environment dbEnv = new Environment(TestUtils.BASETEST_DBFILE, envc); + + // set up a transaction DB. + DatabaseConfig dbConfig = new DatabaseConfig(); + dbConfig.setType(DatabaseType.BTREE); + dbConfig.setAllowCreate(true); + Database db = dbEnv.openDatabase(null, CALLBACKTEST_DBNAME, null, dbConfig); + + DatabaseEntry key1 = new DatabaseEntry("key".getBytes()); + DatabaseEntry data1 = new DatabaseEntry("data".getBytes()); + // populate was doing some more than this (validating that not retrieving things that were not added) + db.putNoOverwrite(null, key1, data1); +// TestUtil.populate(db); + + CheckpointConfig cpcfg = new CheckpointConfig(); + cpcfg.setForce(true); + dbEnv.checkpoint(cpcfg); + + try { + dbConfig.setBtreeComparator(null); + } + catch (IllegalArgumentException dbe) + { + TestUtils.DEBUGOUT(1, "got expected exception: " + dbe); + // ignore + } + + /* + // Pretend we crashed, and reopen the environment + db = null; + dbenv = null; + + dbenv = new DbEnv(0); + dbenv.setFeedbackHandler(this); + dbenv.open(".", Db.DB_INIT_LOCK | Db.DB_INIT_MPOOL | Db.DB_INIT_LOG + | Db.DB_INIT_TXN | Db.DB_RECOVER, 0); + */ + + dbEnv.panic(true); + try { + DatabaseEntry key = new DatabaseEntry("foo".getBytes()); + DatabaseEntry data = new DatabaseEntry(); + db.get(null, key, data, null); + } + catch (DatabaseException dbe2) + { + TestUtils.DEBUGOUT(2, "got expected exception: " + dbe2); + // ignore + } + + } + + /* + * FeedbackHandler interface implementation. + */ + public void recoveryFeedback(Environment dbenv, int percent) + { + TestUtils.DEBUGOUT(2, "recoveryFeedback callback invoked. percent: " + percent); + } + public void upgradeFeedback(Database db, int percent) + { + TestUtils.DEBUGOUT(2, "upgradeFeedback callback invoked. percent: " + percent); + } + public void verifyFeedback(Database db, int percent) + { + TestUtils.DEBUGOUT(2, "verifyFeedback callback invoked. percent: " + percent); + } + + /* + * Panic handler interface implementation. + */ + public void panic(Environment dbenv, DatabaseException e) + { + TestUtils.DEBUGOUT(2, "panic callback invoked. exception: " + e); + } + + /* + * Error handler interface implementation. + */ + public void error(Environment dbenv, String errpfx, String msg) + { + TestUtils.DEBUGOUT(2, "error callback invoked, errpfx: \"" + errpfx + "\", msg: \"" + msg + "\""); + } +} diff --git a/test/java/junit/src/com/sleepycat/db/test/ClosedDbTest.java b/test/java/junit/src/com/sleepycat/db/test/ClosedDbTest.java new file mode 100644 index 00000000..4d0e72b3 --- /dev/null +++ b/test/java/junit/src/com/sleepycat/db/test/ClosedDbTest.java @@ -0,0 +1,86 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. + * + */ + +package com.sleepycat.db.test; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import com.sleepycat.db.*; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; + +import com.sleepycat.db.test.TestUtils; +public class ClosedDbTest { + public static final String CLOSEDDBTEST_DBNAME = "closeddbtest.db"; + @BeforeClass public static void ClassInit() { + TestUtils.loadConfig(null); + TestUtils.check_file_removed(TestUtils.getDBFileName(CLOSEDDBTEST_DBNAME), true, true); + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(CLOSEDDBTEST_DBNAME)); + } + + @AfterClass public static void ClassShutdown() { + TestUtils.check_file_removed(TestUtils.getDBFileName(CLOSEDDBTEST_DBNAME), true, true); + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(CLOSEDDBTEST_DBNAME)); + } + + @Before public void PerTestInit() + throws Exception { + } + + @After public void PerTestShutdown() + throws Exception { + } + /* + * Test case implementations. + * To disable a test mark it with @Ignore + * To set a timeout(ms) notate like: @Test(timeout=1000) + * To indicate an expected exception notate like: (expected=Exception) + */ + + @Test public void test1() + throws DatabaseException, FileNotFoundException + { + DatabaseConfig dbConf = new DatabaseConfig(); + dbConf.setType(DatabaseType.BTREE); + dbConf.setAllowCreate(true); + Database db = new Database(TestUtils.getDBFileName(CLOSEDDBTEST_DBNAME), null, dbConf); + + DatabaseEntry key = new DatabaseEntry("key".getBytes()); + DatabaseEntry data = new DatabaseEntry("data".getBytes()); + db.putNoOverwrite(null, key, data); + + // Now, retrieve. It would be possible to reuse the + // same key object, but that would be a-typical. + DatabaseEntry getkey = new DatabaseEntry("key".getBytes()); + DatabaseEntry badgetkey = new DatabaseEntry("badkey".getBytes()); + DatabaseEntry getdata = new DatabaseEntry(); + getdata.setReuseBuffer(false); // TODO: is this enabling DB_DBT_MALLOC? + + int ret; + + // close the db - subsequent operations should fail by throwing + // an exception. + db.close(); + + try { + db.get(null, getkey, getdata, LockMode.DEFAULT); + fail("Database get on a closed Db should not have completed."); + } catch (IllegalArgumentException e) { + TestUtils.DEBUGOUT(1, "Got expected exception from db.get on closed database."); + } + + } +} + diff --git a/test/java/junit/src/com/sleepycat/db/test/DatabaseTest.java b/test/java/junit/src/com/sleepycat/db/test/DatabaseTest.java new file mode 100644 index 00000000..c3a03885 --- /dev/null +++ b/test/java/junit/src/com/sleepycat/db/test/DatabaseTest.java @@ -0,0 +1,563 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. + * + */ + +/* + * Alexg 23-4-06 + * Based on scr016 TestConstruct01 and TestConstruct02 + * test applications. + */ + +package com.sleepycat.db.test; + +import org.junit.Before; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + +import com.sleepycat.db.Cursor; +import com.sleepycat.db.CursorConfig; +import com.sleepycat.db.Database; +import com.sleepycat.db.DatabaseConfig; +import com.sleepycat.db.DatabaseEntry; +import com.sleepycat.db.DatabaseException; +import com.sleepycat.db.DatabaseType; +import com.sleepycat.db.Environment; +import com.sleepycat.db.EnvironmentConfig; +import com.sleepycat.db.HeapStats; +import com.sleepycat.db.LockMode; +import com.sleepycat.db.OperationStatus; +import com.sleepycat.db.Transaction; + +import java.io.File; +import java.io.IOException; +import java.io.FileNotFoundException; +import com.sleepycat.db.test.TestUtils; + +public class DatabaseTest { + + public static final String DATABASETEST_DBNAME = "databasetest.db"; + + private static int itemcount; // count the number of items in the database + + @BeforeClass public static void ClassInit() { + TestUtils.loadConfig(null); + TestUtils.check_file_removed(TestUtils.getDBFileName(DATABASETEST_DBNAME), true, true); + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(DATABASETEST_DBNAME)); + itemcount = 0; + } + + @AfterClass public static void ClassShutdown() { + TestUtils.check_file_removed(TestUtils.getDBFileName(DATABASETEST_DBNAME), true, true); + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(DATABASETEST_DBNAME)); + } + + @Before public void PerTestInit() + throws Exception { + } + + @After public void PerTestShutdown() + throws Exception { + } + + /* + * Test creating a new database. + */ + @Test public void test1() + throws DatabaseException, FileNotFoundException + { + TestOptions options = new TestOptions(); + options.db_config.setErrorPrefix("DatabaseTest::test1 "); + + rundb(itemcount++, options); + } + + /* + * Test opening and adding to an existing database. + */ + @Test public void test2() + throws DatabaseException, FileNotFoundException + { + TestOptions options = new TestOptions(); + options.db_config.setErrorPrefix("DatabaseTest::test2 "); + + rundb(itemcount++, options); + } + + /* + * Test modifying the error prefix multiple times ? + */ + @Test public void test3() + throws DatabaseException, FileNotFoundException + { + TestOptions options = new TestOptions(); + options.db_config.setErrorPrefix("DatabaseTest::test3 "); + + for (int i=0; i<100; i++) + options.db_config.setErrorPrefix("str" + i); + + rundb(itemcount++, options); + } + + /* + * Test opening a database with an env. + */ + @Test public void test4() + throws DatabaseException, FileNotFoundException + { + TestOptions options = new TestOptions(); + options.db_config.setErrorPrefix("DatabaseTest::test4 "); + + EnvironmentConfig envc = new EnvironmentConfig(); + envc.setAllowCreate(true); + envc.setInitializeCache(true); + options.db_env = new Environment(TestUtils.BASETEST_DBFILE, envc); + + rundb(itemcount++, options); + options.db_env.close(); + } + + /* + * Test opening multiple databases using the same env. + */ + @Test public void test5() + throws DatabaseException, FileNotFoundException + { + TestOptions options = new TestOptions(); + options.db_config.setErrorPrefix("DatabaseTest::test5 "); + + EnvironmentConfig envc = new EnvironmentConfig(); + envc.setAllowCreate(true); + envc.setInitializeCache(true); + options.db_env = new Environment(TestUtils.BASETEST_DBFILE, envc); + + rundb(itemcount++, options); + + rundb(itemcount++, options); + + options.db_env.close(); + } + + /* + * Test just opening and closing a DB and an Env without doing any operations. + */ + @Test public void test6() + throws DatabaseException, FileNotFoundException + { + TestOptions options = new TestOptions(); + options.db_config.setErrorPrefix("DatabaseTest::test6 "); + + Database db = new Database(TestUtils.getDBFileName(DATABASETEST_DBNAME), null, options.db_config); + + EnvironmentConfig envc = new EnvironmentConfig(); + envc.setAllowCreate(true); + envc.setInitializeCache(true); + Environment db_env = new Environment(TestUtils.BASETEST_DBFILE, envc); + + db.close(); + db_env.close(); + + System.gc(); + System.runFinalization(); + } + + /* + * test7 leaves a db and dbenv open; it should be detected. + */ + /* Not sure if relevant with current API. + @Test public void test7() + throws DatabaseException, FileNotFoundException + { + TestOptions options = new TestOptions(); + options.db_config.setErrorPrefix("DatabaseTest::test7 "); + + Database db = new Database(TestUtils.getDBFileName(DATABASETEST_DBNAME), null, options.db_config); + + EnvironmentConfig envc = new EnvironmentConfig(); + envc.setAllowCreate(true); + envc.setInitializeCache(true); + Environment db_env = new Environment(TestUtils.BASETEST_DBFILE, envc); + + System.gc(); + System.runFinalization(); + } + */ + /* + * Test leaving database and cursors open won't harm. + */ + @Test public void test10() + throws DatabaseException, FileNotFoundException + { + System.out.println("\nTest 10 transactional."); + test10_int(true); + System.out.println("\nTest 10 non-transactional."); + test10_int(false); + } + + void test10_int(boolean havetxn) + throws DatabaseException, FileNotFoundException + { + String name; + Transaction txn = null; + + itemcount = 0; + TestOptions options = new TestOptions(); + options.save_db = true; + options.db_config.setErrorPrefix("DatabaseTest::test10 "); + + EnvironmentConfig envc = new EnvironmentConfig(); + envc.setAllowCreate(true); + envc.setInitializeCache(true); + envc.setPrivate(true); + if (havetxn) { + envc.setInitializeLogging(true); + envc.setInitializeLocking(true); + envc.setTransactional(true); + } + options.db_env = new Environment(null, envc); + + if (havetxn) + txn = options.db_env.beginTransaction(null, null); + try { + options.db_config.setAllowCreate(true); + options.database = options.db_env.openDatabase(txn, null, null, options.db_config); + + // Acquire a cursor for the database and use it to insert data, but don't close it. + Cursor dbc = options.database.openCursor(txn, CursorConfig.DEFAULT); + + DatabaseEntry key = new DatabaseEntry(); + DatabaseEntry data = new DatabaseEntry(); + byte bytes[] = new byte[4]; + int ii; + for (int i = 0; i < 100; i++) { + ii = i; + bytes[0] = (byte)ii; + ii >>= 8; + bytes[1] = (byte)ii; + ii >>= 8; + bytes[2] = (byte)ii; + ii >>= 8; + bytes[3] = (byte)ii; + key.setData(bytes); + key.setSize(bytes.length); + data.setData(bytes); + data.setSize(bytes.length); + + dbc.putKeyLast(key, data); + } + // Do not close dbc. + + // Acquire a cursor for the database and use it to read data, but don't close it. + Cursor csr = options.database.openCursor(txn, CursorConfig.DEFAULT); + int i = 0; + while (i < 100 && csr.getNext(key, data, LockMode.DEFAULT) == OperationStatus.SUCCESS) { + i++; + } + // Do not close csr. + if (havetxn) + txn.commit(); + } catch (DatabaseException e) { + if (havetxn && txn != null) + txn.abort(); + } + // Do not close options.database + options.db_env.closeForceSync(); + } + /* + * Test creating a new database. + */ + @Test public void test8() + throws DatabaseException, FileNotFoundException + { + TestUtils.removeall(true, false, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(DATABASETEST_DBNAME)); + itemcount = 0; + TestOptions options = new TestOptions(); + options.save_db = true; + options.db_config.setErrorPrefix("DatabaseTest::test8 "); + + EnvironmentConfig envc = new EnvironmentConfig(); + envc.setAllowCreate(true); + envc.setInitializeCache(true); + options.db_env = new Environment(TestUtils.BASETEST_DBFILE, envc); + + // stop rundb from closing the database, and pass in one created. + rundb(itemcount++, options); + rundb(itemcount++, options); + rundb(itemcount++, options); + rundb(itemcount++, options); + rundb(itemcount++, options); + rundb(itemcount++, options); + + options.database.close(); + options.database = null; + + // reopen the same database. + rundb(itemcount++, options); + rundb(itemcount++, options); + rundb(itemcount++, options); + rundb(itemcount++, options); + rundb(itemcount++, options); + rundb(itemcount++, options); + + options.database.close(); + options.database = null; + + } + + /* + * Test setting database handle exclusive lock. + */ + @Test public void test11() + throws DatabaseException, FileNotFoundException + { + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(DATABASETEST_DBNAME)); + itemcount = 0; + TestOptions options = new TestOptions(); + options.save_db = true; + options.db_config.setErrorPrefix("DatabaseTest::test11 "); + + EnvironmentConfig envc = new EnvironmentConfig(); + envc.setAllowCreate(true); + envc.setInitializeCache(true); + envc.setInitializeLogging(true); + envc.setInitializeLocking(true); + envc.setTransactional(true); + envc.setThreaded(false); + options.db_env = new Environment(TestUtils.BASETEST_DBFILE, envc); + + rundb(itemcount++, options); + assertNull(options.database.getConfig().getNoWaitDbExclusiveLock()); + + options.database.close(); + options.database = null; + + options.db_config.setNoWaitDbExclusiveLock(Boolean.TRUE); + rundb(itemcount++, options); + assertEquals(options.database.getConfig().getNoWaitDbExclusiveLock(), Boolean.TRUE); + + options.database.close(); + options.database = null; + + options.db_config.setNoWaitDbExclusiveLock(Boolean.FALSE); + rundb(itemcount++, options); + assertEquals(options.database.getConfig().getNoWaitDbExclusiveLock(), Boolean.FALSE); + + // Test noWaitDbExclusiveLock can not be set after database is opened. + try { + DatabaseConfig newConfig = options.database.getConfig(); + newConfig.setNoWaitDbExclusiveLock(Boolean.TRUE); + options.database.setConfig(newConfig); + } catch (IllegalArgumentException e) { + } finally { + options.database.close(); + options.database = null; + options.db_env.close(); + } + } + + /* + * Test setting metadata directory + */ + @Test public void test12() + throws DatabaseException, FileNotFoundException + { + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(DATABASETEST_DBNAME)); + itemcount = 0; + TestOptions options = new TestOptions(); + options.db_config.setErrorPrefix("DatabaseTest::test12 "); + + EnvironmentConfig envc = new EnvironmentConfig(); + envc.setAllowCreate(true); + envc.setInitializeCache(true); + + options.db_env = new Environment(TestUtils.BASETEST_DBFILE, envc); + rundb(itemcount++, options); + assertNull(options.db_env.getConfig().getMetadataDir()); + options.db_env.close(); + + String mddir = "metadataDir"; + envc.setMetadataDir(new java.io.File(mddir)); + options.db_env = new Environment(TestUtils.BASETEST_DBFILE, envc); + rundb(itemcount++, options); + assertEquals(options.db_env.getConfig().getMetadataDir().getPath(), mddir); + options.db_env.close(); + } + + /* + * Test setting heap region size + */ + @Test public void test13() + throws DatabaseException, FileNotFoundException + { + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(DATABASETEST_DBNAME)); + TestOptions options = new TestOptions(); + options.db_config.setErrorPrefix("DatabaseTest::test13 "); + options.db_config.setAllowCreate(true); + options.db_config.setType(DatabaseType.HEAP); + options.db_config.setHeapRegionSize(4); + + Database db = new Database(TestUtils.getDBFileName(DATABASETEST_DBNAME), null, options.db_config); + assertEquals(db.getConfig().getHeapRegionSize(), 4); + + HeapStats stats = (HeapStats)db.getStats(null, null); + assertEquals(stats.getHeapRegionSize(), 4); + + db.close(); + } + + // Check that key/data for 0 - count-1 are already present, + // and write a key/data for count. The key and data are + // both "0123...N" where N == count-1. + // + // For some reason on Windows, we need to open using the full pathname + // of the file when there is no environment, thus the 'has_env' + // variable. + // + void rundb(int count, TestOptions options) + throws DatabaseException, FileNotFoundException + { + String name; + + Database db; + if(options.database == null) + { + if (options.db_env != null) + name = DATABASETEST_DBNAME; + else + name = TestUtils.getDBFileName(DATABASETEST_DBNAME); + + if(count == 0) + options.db_config.setAllowCreate(true); + + if(options.db_env == null) + db = new Database(name, null, options.db_config); + else + db = options.db_env.openDatabase(options.txn, name, null, options.db_config); + } else { + db = options.database; + } + + // The bit map of keys we've seen + long bitmap = 0; + + // The bit map of keys we expect to see + long expected = (1 << (count+1)) - 1; + + byte outbuf[] = new byte[count+1]; + int i; + for (i=0; i<count; i++) { + outbuf[i] = (byte)('0' + i); + } + outbuf[i++] = (byte)'x'; + + DatabaseEntry key = new DatabaseEntry(outbuf, 0, i); + DatabaseEntry data = new DatabaseEntry(outbuf, 0, i); + + TestUtils.DEBUGOUT("Put: " + (char)outbuf[0] + ": " + new String(outbuf, 0, i)); + db.putNoOverwrite(options.txn, key, data); + + // Acquire a cursor for the table. + Cursor dbcp = db.openCursor(options.txn, CursorConfig.DEFAULT); + + // Walk through the table, checking + DatabaseEntry readkey = new DatabaseEntry(); + DatabaseEntry readdata = new DatabaseEntry(); + DatabaseEntry whoknows = new DatabaseEntry(); + + /* + * NOTE: Maybe want to change from user-buffer to DB buffer + * depending on the flag options.user_buffer (setReuseBuffer) + * The old version set MALLOC/REALLOC here - not sure if it is the same. + */ + + TestUtils.DEBUGOUT("Dbc.get"); + while (dbcp.getNext(readkey, readdata, LockMode.DEFAULT) == OperationStatus.SUCCESS) { + String key_string = + new String(readkey.getData(), 0, readkey.getSize()); + String data_string = + new String(readdata.getData(), 0, readkey.getSize()); + TestUtils.DEBUGOUT("Got: " + key_string + ": " + data_string); + int len = key_string.length(); + if (len <= 0 || key_string.charAt(len-1) != 'x') { + TestUtils.ERR("reread terminator is bad"); + } + len--; + long bit = (1 << len); + if (len > count) { + TestUtils.ERR("reread length is bad: expect " + count + " got "+ len + " (" + key_string + ")" ); + } + else if (!data_string.equals(key_string)) { + TestUtils.ERR("key/data don't match"); + } + else if ((bitmap & bit) != 0) { + TestUtils.ERR("key already seen"); + } + else if ((expected & bit) == 0) { + TestUtils.ERR("key was not expected"); + } + else { + bitmap |= bit; + expected &= ~(bit); + for (i=0; i<len; i++) { + if (key_string.charAt(i) != ('0' + i)) { + System.out.print(" got " + key_string + + " (" + (int)key_string.charAt(i) + + "), wanted " + i + + " (" + (int)('0' + i) + + ") at position " + i + "\n"); + TestUtils.ERR("key is corrupt"); + } + } + } + } + if (expected != 0) { + System.out.print(" expected more keys, bitmap is: " + expected + "\n"); + TestUtils.ERR("missing keys in database"); + } + + dbcp.close(); + TestUtils.DEBUGOUT("options.save_db " + options.save_db + " options.database " + options.database); + if(options.save_db == false) + db.close(false); + else if (options.database == null) + options.database = db; + } +} + + +class TestOptions +{ + int testmask = 0; // which tests to run + int user_buffer = 0; // use DB_DBT_USERMEM or DB_DBT_MALLOC + int successcounter =0; + boolean save_db = false; + Environment db_env = null; + DatabaseConfig db_config; + Database database = null; // db is saved here by rundb if save_db is true. + Transaction txn = null; + + public TestOptions() + { + this.testmask = 0; + this.user_buffer = 0; + this.successcounter = 0; + this.db_env = null; + this.txn = null; + + db_config = new DatabaseConfig(); + db_config.setErrorStream(TestUtils.getErrorStream()); + db_config.setErrorPrefix("DatabaseTest"); + db_config.setType(DatabaseType.BTREE); + // We don't really care about the pagesize + db_config.setPageSize(1024); + + } + +} diff --git a/test/java/junit/src/com/sleepycat/db/test/EncryptTest.java b/test/java/junit/src/com/sleepycat/db/test/EncryptTest.java new file mode 100644 index 00000000..57c6faba --- /dev/null +++ b/test/java/junit/src/com/sleepycat/db/test/EncryptTest.java @@ -0,0 +1,138 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. + * + */ + +package com.sleepycat.db.test; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import com.sleepycat.db.*; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.UnsupportedEncodingException; + +import com.sleepycat.db.test.TestUtils; +public class EncryptTest { + public static final String ENCRYPTTEST_DBNAME = "encrypttest.db"; + @BeforeClass public static void ClassInit() { + TestUtils.loadConfig(null); + TestUtils.check_file_removed(TestUtils.getDBFileName(ENCRYPTTEST_DBNAME), true, true); + } + + @AfterClass public static void ClassShutdown() { + TestUtils.check_file_removed(TestUtils.getDBFileName(ENCRYPTTEST_DBNAME), true, true); + } + + @Before public void PerTestInit() + throws Exception { + TestUtils.check_file_removed(TestUtils.getDBFileName(ENCRYPTTEST_DBNAME), true, true); + } + + @After() public void PerTestShutdown() + throws Exception { + TestUtils.check_file_removed(TestUtils.getDBFileName(ENCRYPTTEST_DBNAME), true, true); + } + /* + * Test case implementations. + * To disable a test mark it with @Ignore + * To set a timeout(ms) notate like: @Test(timeout=1000) + * To indicate an expected exception notate like: (expected=Exception) + */ + + /* + * Test the basic db no env and encryption disabled. + */ + @Test public void test1() + throws DatabaseException, FileNotFoundException, UnsupportedEncodingException + { + DatabaseConfig dbConf = new DatabaseConfig(); + dbConf.setType(DatabaseType.BTREE); + dbConf.setAllowCreate(true); + + Database db = new Database(TestUtils.getDBFileName(ENCRYPTTEST_DBNAME), null, dbConf); + + DatabaseEntry key = new DatabaseEntry("key".getBytes("UTF-8")); + DatabaseEntry data = new DatabaseEntry("data".getBytes("UTF-8")); + + db.put(null, key, data); + + db.close(); + //try { Thread.sleep(10000); } catch(InterruptedException e) {} + + if(!findData("key")) + fail("Did not find the un-encrypted value in the database file after close"); + } + + /* + * Test database with encryption, no env. + */ + @Test public void test2() + throws DatabaseException, FileNotFoundException, UnsupportedEncodingException + { + DatabaseConfig dbConf = new DatabaseConfig(); + dbConf.setType(DatabaseType.BTREE); + dbConf.setAllowCreate(true); + dbConf.setEncrypted("password"); + dbConf.setErrorStream(System.err); + + Database db = new Database(TestUtils.getDBFileName(ENCRYPTTEST_DBNAME), null, dbConf); + + DatabaseEntry key = new DatabaseEntry("key".getBytes("UTF-8")); + DatabaseEntry data = new DatabaseEntry("data".getBytes("UTF-8")); + + db.put(null, key, data); + + db.sync(); + db.close(); + + if (findData("key")) + fail("Found the un-encrypted value in an encrypted database file after close"); + } + + private boolean findData(String toFind) + { + boolean found = false; + try { + String dbname = TestUtils.getDBFileName(ENCRYPTTEST_DBNAME); + File f = new File(dbname); + if (!f.exists() || f.isDirectory()) { + TestUtils.ERR("Could not find database file: " + dbname + " to look for encrypted string."); + return false; + } + FileInputStream fin = new FileInputStream(f); + byte[] buf = new byte[(int)f.length()]; + fin.read(buf, 0, (int)f.length()); + fin.close(); + + TestUtils.DEBUGOUT(1, "EncryptTest findData file length: " + buf.length); + byte firstbyte = (toFind.getBytes("UTF-8"))[0]; + // buf can contain non-ascii characters, so no easy string search + for (int i = 0; i < buf.length - toFind.length(); i++) + { + if (buf[i] == firstbyte) + { + if(toFind.compareTo(new String(buf, i, toFind.length())) == 0) + { + found = true; + break; + } + } + } + } catch(Exception e) { + } + return found; + } +} diff --git a/test/java/junit/src/com/sleepycat/db/test/EnvRegionSizeTest.java b/test/java/junit/src/com/sleepycat/db/test/EnvRegionSizeTest.java new file mode 100644 index 00000000..4259c6df --- /dev/null +++ b/test/java/junit/src/com/sleepycat/db/test/EnvRegionSizeTest.java @@ -0,0 +1,133 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. + * + */ + + +package com.sleepycat.db.test; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import com.sleepycat.db.*; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; + +import com.sleepycat.db.test.TestUtils; +public class EnvRegionSizeTest { + public static final String ENVREGIONSIZETEST_DBNAME = "envregionsizetest.db"; + @BeforeClass public static void ClassInit() { + TestUtils.loadConfig(null); + TestUtils.check_file_removed(TestUtils.getDBFileName(ENVREGIONSIZETEST_DBNAME), true, true); + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(ENVREGIONSIZETEST_DBNAME)); + } + + @AfterClass public static void ClassShutdown() { + TestUtils.check_file_removed(TestUtils.getDBFileName(ENVREGIONSIZETEST_DBNAME), true, true); + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(ENVREGIONSIZETEST_DBNAME)); + } + + @Before public void PerTestInit() + throws Exception { + } + + @After public void PerTestShutdown() + throws Exception { + } + /* + * Test case implementations. + * To disable a test mark it with @Ignore + * To set a timeout(ms) notate like: @Test(timeout=1000) + * To indicate an expected exception notate like: (expected=Exception) + */ + + @Test public void testRegionMemoryInitialSize() + throws DatabaseException, FileNotFoundException + { + /* Create an environment. */ + EnvironmentConfig envc = new EnvironmentConfig(); + envc.setAllowCreate(true); + envc.setInitializeCache(true); + envc.setRegionMemoryInitialSize(RegionResourceType.LOCK, 1024); + envc.setRegionMemoryInitialSize(RegionResourceType.LOCK_OBJECT, 1024); + envc.setRegionMemoryInitialSize(RegionResourceType.LOCKER, 1024); + envc.setRegionMemoryInitialSize(RegionResourceType.LOG_ID, 1024); + envc.setRegionMemoryInitialSize(RegionResourceType.TRANSACTION, 1024); + envc.setRegionMemoryInitialSize(RegionResourceType.THREAD, 1024); + + /* Check to see that they "stuck" before opening env. */ + assertEquals( + envc.getRegionMemoryInitialSize(RegionResourceType.LOCK), 1024); + assertEquals( + envc.getRegionMemoryInitialSize(RegionResourceType.LOCK_OBJECT), 1024); + assertEquals( + envc.getRegionMemoryInitialSize(RegionResourceType.LOCKER), 1024); + assertEquals( + envc.getRegionMemoryInitialSize(RegionResourceType.LOG_ID), 1024); + assertEquals( + envc.getRegionMemoryInitialSize(RegionResourceType.TRANSACTION), 1024); + assertEquals( + envc.getRegionMemoryInitialSize(RegionResourceType.THREAD), 1024); + + Environment dbEnv = new Environment(TestUtils.BASETEST_DBFILE, envc); + + /* Check again after opnening. */ + assertEquals( + envc.getRegionMemoryInitialSize(RegionResourceType.LOCK), 1024); + assertEquals( + envc.getRegionMemoryInitialSize(RegionResourceType.LOCK_OBJECT), 1024); + assertEquals( + envc.getRegionMemoryInitialSize(RegionResourceType.LOCKER), 1024); + assertEquals( + envc.getRegionMemoryInitialSize(RegionResourceType.LOG_ID), 1024); + assertEquals( + envc.getRegionMemoryInitialSize(RegionResourceType.TRANSACTION), 1024); + assertEquals( + envc.getRegionMemoryInitialSize(RegionResourceType.THREAD), 1024); + } + + @Test public void testLockTableSize() + throws DatabaseException, FileNotFoundException + { + EnvironmentConfig envc = new EnvironmentConfig(); + envc.setAllowCreate(true); + envc.setInitializeCache(true); + envc.setLockTableSize(1024); + assertEquals(envc.getLockTableSize(), 1024); + Environment dbEnv = new Environment(TestUtils.BASETEST_DBFILE, envc); + assertEquals(envc.getLockTableSize(), 1024); + } + + @Test public void testInitialMutexes() + throws DatabaseException, FileNotFoundException + { + EnvironmentConfig envc = new EnvironmentConfig(); + envc.setAllowCreate(true); + envc.setInitializeCache(true); + envc.setInitialMutexes(1024); + assertEquals(envc.getInitialMutexes(), 1024); + Environment dbEnv = new Environment(TestUtils.BASETEST_DBFILE, envc); + assertEquals(envc.getInitialMutexes(), 1024); + } + + @Test public void testRegionMemoryMax() + throws DatabaseException, FileNotFoundException + { + EnvironmentConfig envc = new EnvironmentConfig(); + envc.setAllowCreate(true); + envc.setInitializeCache(true); + envc.setRegionMemoryMax(5 * 1024 * 1024); + assertEquals(envc.getRegionMemoryMax(), 5 * 1024 * 1024); + Environment dbEnv = new Environment(TestUtils.BASETEST_DBFILE, envc); + assertEquals(envc.getRegionMemoryMax(), 5 * 1024 * 1024); + } +} diff --git a/test/java/junit/src/com/sleepycat/db/test/HashCompareTest.java b/test/java/junit/src/com/sleepycat/db/test/HashCompareTest.java new file mode 100644 index 00000000..18d11f57 --- /dev/null +++ b/test/java/junit/src/com/sleepycat/db/test/HashCompareTest.java @@ -0,0 +1,125 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. + * + */ + + +package com.sleepycat.db.test; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import com.sleepycat.db.*; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; + +import com.sleepycat.db.test.TestUtils; +public class HashCompareTest { + public static final String HASHCOMPARETEST_DBNAME = "hashcomparetest.db"; + @BeforeClass public static void ClassInit() { + TestUtils.loadConfig(null); + TestUtils.check_file_removed(TestUtils.getDBFileName(HASHCOMPARETEST_DBNAME), true, true); + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(HASHCOMPARETEST_DBNAME)); + } + + @AfterClass public static void ClassShutdown() { + TestUtils.check_file_removed(TestUtils.getDBFileName(HASHCOMPARETEST_DBNAME), true, true); + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(HASHCOMPARETEST_DBNAME)); + } + + @Before public void PerTestInit() + throws Exception { + TestUtils.check_file_removed(TestUtils.getDBFileName(HASHCOMPARETEST_DBNAME), true, true); + java.io.File dbfile = new File(HASHCOMPARETEST_DBNAME); + dbfile.delete(); + } + + @After public void PerTestShutdown() + throws Exception { + } + /* + * Test case implementations. + * To disable a test mark it with @Ignore + * To set a timeout(ms) notate like: @Test(timeout=1000) + * To indicate an expected exception notate like: (expected=Exception) + */ + + @Test public void test1() + throws DatabaseException, FileNotFoundException + { + runTest(DatabaseType.HASH); + } + + @Test public void test2() + throws DatabaseException, FileNotFoundException + { + runTest(DatabaseType.BTREE); + } + + public void runTest(DatabaseType type) + throws DatabaseException, FileNotFoundException + { + int i; + DatabaseConfig conf = new DatabaseConfig(); + conf.setErrorStream(TestUtils.getErrorStream()); + conf.setErrorPrefix("HashCompareTest"); + conf.setType(type); + if (type == DatabaseType.HASH) { + conf.setHashComparator(new HashComparator()); + } else + conf.setBtreeComparator(new BtreeComparator()); + conf.setAllowCreate(true); + + Database db = new Database(HASHCOMPARETEST_DBNAME, null, conf); + + DatabaseEntry key = new DatabaseEntry(); + DatabaseEntry data = new DatabaseEntry("world".getBytes()); + for (i = 0; i < 100; i++) { + key.setData((new String("key"+i)).getBytes()); + db.put(null, key, data); + } + i = 0; + Cursor dbc; + dbc = db.openCursor(null, CursorConfig.DEFAULT); + while (dbc.getNext(key, data, LockMode.DEFAULT) == + OperationStatus.SUCCESS) { + ++i; + } +// System.out.println("retrieved " + i + " entries"); + dbc.close(); + db.close(); + + } +} + +class HashComparator implements java.util.Comparator +{ + public int compare(Object o1, Object o2) { +// System.out.println("Comparing: " + o1 + ":"+o2); + String s1, s2; + s1 = new String((byte[])o1); + s2 = new String((byte[])o2); + return s1.compareToIgnoreCase(s2); + } +} + +class BtreeComparator implements java.util.Comparator +{ + public int compare(Object o1, Object o2) { + //System.out.println("Comparing: " + o1 + ":"+o2); + String s1, s2; + s1 = new String((byte[])o1); + s2 = new String((byte[])o2); + return s1.compareToIgnoreCase(s2); + } +} diff --git a/test/java/junit/src/com/sleepycat/db/test/LogCursorTest.java b/test/java/junit/src/com/sleepycat/db/test/LogCursorTest.java new file mode 100644 index 00000000..b6a5b08b --- /dev/null +++ b/test/java/junit/src/com/sleepycat/db/test/LogCursorTest.java @@ -0,0 +1,101 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. + * + */ + + +package com.sleepycat.db.test; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import com.sleepycat.db.*; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; + +import com.sleepycat.db.test.TestUtils; +public class LogCursorTest { + public static final String LOGCURSORTEST_DBNAME = "logcursortest.db"; + @BeforeClass public static void ClassInit() { + TestUtils.loadConfig(null); + TestUtils.check_file_removed(TestUtils.getDBFileName(LOGCURSORTEST_DBNAME), true, true); + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(LOGCURSORTEST_DBNAME)); + } + + @AfterClass public static void ClassShutdown() { + TestUtils.check_file_removed(TestUtils.getDBFileName(LOGCURSORTEST_DBNAME), true, true); + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(LOGCURSORTEST_DBNAME)); + } + + @Before public void PerTestInit() + throws Exception { + } + + @After public void PerTestShutdown() + throws Exception { + } + /* + * Test case implementations. + * To disable a test mark it with @Ignore + * To set a timeout(ms) notate like: @Test(timeout=1000) + * To indicate an expected exception notate like: (expected=Exception) + */ + + @Test public void test1() + throws DatabaseException, FileNotFoundException + { + Environment env; + EnvironmentConfig envCfg; + Database db; + DatabaseConfig cfg; + File home; + int key_count = 50, lc_count = 0; + + envCfg = new EnvironmentConfig(); + envCfg.setAllowCreate(true); + envCfg.setInitializeCache(true); + envCfg.setInitializeLocking(true); + envCfg.setInitializeLogging(true); + envCfg.setMaxLogFileSize(32768); + envCfg.setTransactional(true); + + env = new Environment(TestUtils.BASETEST_DBFILE, envCfg); + + cfg = new DatabaseConfig(); + cfg.setAllowCreate(true); + cfg.setType(DatabaseType.BTREE); + cfg.setTransactional(true); + db = env.openDatabase(null, LOGCURSORTEST_DBNAME, null, cfg); + + for (int i =0; i < key_count; i++) { + DatabaseEntry key = new DatabaseEntry(); + key.setData(String.valueOf(i).getBytes()); + DatabaseEntry data =new DatabaseEntry(); + data.setData(String.valueOf(500-i).getBytes()); + db.put(null, key, data); + } + + LogCursor lc = env.openLogCursor(); + LogSequenceNumber lsn = new LogSequenceNumber(); + DatabaseEntry dbt = new DatabaseEntry(); + while (lc.getNext(lsn, dbt) == OperationStatus.SUCCESS) + lc_count++; + lc.close(); + db.close(); + env.close(); + // There should be at least as many log entries as there were + // keys inserted. + assertTrue(lc_count > key_count); + + } +} diff --git a/test/java/junit/src/com/sleepycat/db/test/MultipleCursorTest.java b/test/java/junit/src/com/sleepycat/db/test/MultipleCursorTest.java new file mode 100644 index 00000000..e7374d31 --- /dev/null +++ b/test/java/junit/src/com/sleepycat/db/test/MultipleCursorTest.java @@ -0,0 +1,241 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. + * + */ + + +package com.sleepycat.db.test; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import com.sleepycat.db.*; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; + +import com.sleepycat.db.test.TestUtils; + +public class MultipleCursorTest { + public static final String MULTIPLECURSORTEST_DBNAME = "multiplecursortest.db"; + + /* The data used by this test. */ + private static final String[] Key_Strings = { + "abc", + "def", + "ghi", + "jkl", + "mno", + "pqr", + "stu", + "vwx", + "yza", + "bcd", + "efg", + "hij", + "klm", + "nop", + "qrs", + "tuv", + "wxy", + }; + private static boolean verbose = false; + @BeforeClass public static void ClassInit() { + TestUtils.loadConfig(null); + TestUtils.check_file_removed(TestUtils.getDBFileName(MULTIPLECURSORTEST_DBNAME), true, true); + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(MULTIPLECURSORTEST_DBNAME)); + } + + @AfterClass public static void ClassShutdown() { + TestUtils.check_file_removed(TestUtils.getDBFileName(MULTIPLECURSORTEST_DBNAME), true, true); + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(MULTIPLECURSORTEST_DBNAME)); + } + + @Before public void PerTestInit() + throws Exception { + } + + @After public void PerTestShutdown() + throws Exception { + } + public static void main(String []argv) { + verbose = true; + if (argv.length > 0 && argv[0].equals("-s")) { + try { + java.lang.Thread.sleep(15*1000); + } catch (InterruptedException e) { + } + } + try { + MultipleCursorTest mpt = new MultipleCursorTest(); + mpt.testMultiplePut(); + mpt.testMultipleDelete(); + } catch (DatabaseException dbe) { + System.out.println("MultipleCursorTest threw DatabaseException"); + } catch (FileNotFoundException fnfe) { + System.out.println("MultipleCursorTest threw FileNotFound"); + } + } + /* + * Test case implementations. + * To disable a test mark it with @Ignore + * To set a timeout(ms) notate like: @Test(timeout=1000) + * To indicate an expected exception notate like: (expected=Exception) + */ + + @Test public void testMultiplePut() + throws DatabaseException, FileNotFoundException + { + Database db = createDatabase(); + byte [] buffer = new byte[1024]; + byte [] buffer2 = new byte[1024]; + int i; + + /* Build up a bulk key/data pair. */ + MultipleKeyDataEntry kd = new MultipleKeyDataEntry(buffer); + DatabaseEntry key = new DatabaseEntry(); + DatabaseEntry data = new DatabaseEntry(); + /* Put 3 in the first round. */ + for (i = 0; i < 3; i++) { + key.setData(Key_Strings[i].getBytes()); + data.setData(Key_Strings[i].getBytes()); + kd.append(key, data); + } + if (verbose) + System.out.println("Built up a multi-key/data buffer."); + db.putMultipleKey(null, kd, false); + if (verbose) + System.out.println("Put a multi-key/data buffer."); + + /* Build up separate bulk key/data DatabaseEntries */ + MultipleDataEntry keys = new MultipleDataEntry(buffer); + MultipleDataEntry datas = new MultipleDataEntry(buffer2); + /* Put 3 in the second round. */ + for (; i < 6; i++) { + key.setData(Key_Strings[i].getBytes()); + data.setData(Key_Strings[i].getBytes()); + keys.append(key); + datas.append(data); + } + if (verbose) + System.out.println("Built up multi-key and data buffers."); + db.putMultiple(null, keys, datas, false); + if (verbose) + System.out.println("Put multi-key and data buffers."); + + // Bulk cursor, adding single items. + Cursor dbc = db.openCursor(null, CursorConfig.BULK_CURSOR); + for (; i < 12; i++) { + key.setData(Key_Strings[i].getBytes()); + data.setData(Key_Strings[i].getBytes()); + dbc.put(key, data); + } + dbc.close(); + + if (verbose) + dumpDatabase(db); + db.close(); + } + @Test public void testMultipleDelete() + throws DatabaseException, FileNotFoundException + { + byte [] buffer = new byte[1024]; + int i; + Database db = createDatabase(); + populateDatabase(db, 0); + + /* Build up separate bulk key/data DatabaseEntries */ + MultipleDataEntry keys = new MultipleDataEntry(buffer); + DatabaseEntry key = new DatabaseEntry(); + /* Put 3 in the second round. */ + for (i = 0; i < 6; i++) { + key.setData(Key_Strings[i].getBytes()); + keys.append(key); + } + db.deleteMultiple(null, keys); + // Bulk cursor, adding single items. + DatabaseEntry data = new DatabaseEntry(); + Cursor dbc = db.openCursor(null, CursorConfig.BULK_CURSOR); + for (; i < 12; i++) { + key.setData(Key_Strings[i].getBytes()); + dbc.getSearchKey(key, data, LockMode.DEFAULT); + dbc.delete(); + } + dbc.close(); + + // Should have about 3 entries left. + if (verbose) + dumpDatabase(db); + db.close(); + } + + /* Not implemented yet. + @Test public void testMultipleGet() + throws DatabaseException, FileNotFoundException + { + Database db = createDatabase(); + populateDatabase(db, 0); + } + */ + + private Database createDatabase() + throws DatabaseException, FileNotFoundException + { + /* Create database. */ + Database db; + DatabaseConfig db_config = new DatabaseConfig(); + String name = TestUtils.getDBFileName(MULTIPLECURSORTEST_DBNAME); + + db_config.setAllowCreate(true); + db_config.setType(DatabaseType.BTREE); + db_config.setSortedDuplicates(true); + + db = new Database(name, null, db_config); + return db; + } + + private void populateDatabase(Database db, int duplicates) + throws DatabaseException, FileNotFoundException + { + DatabaseEntry key = new DatabaseEntry(); + DatabaseEntry data = new DatabaseEntry(); + for (int i = 0; i < Key_Strings.length; i++) { + String datastr = new Integer(i).toString() + Key_Strings[i] + Key_Strings[i]; + key.setData(Key_Strings[i].getBytes()); + data.setData(datastr.getBytes()); + db.put(null, key, data); + for (int j = 0; j < duplicates; j++) { + datastr = new Integer(j).toString() + datastr + Key_Strings[i]; + data.setData(datastr.getBytes()); + db.put(null, key, data); + + } + } + } + + private void dumpDatabase(Database db) { + try { + Cursor dbc = db.openCursor(null, CursorConfig.DEFAULT); + DatabaseEntry key = new DatabaseEntry(); + DatabaseEntry data = new DatabaseEntry(); + + System.out.println("Dumping database contents:"); + while (dbc.getNext(key, data, LockMode.DEFAULT) != OperationStatus.NOTFOUND) { + System.out.println("\tGot key : " + new String(key.getData())); + System.out.println("\t data: " + new String(data.getData())); + } + System.out.println("Finished dumping database contents."); + } catch (DatabaseException dbe) { + System.err.println("dumpDatabase caught an exception."); + } + } + +} diff --git a/test/java/junit/src/com/sleepycat/db/test/PartialGetTest.java b/test/java/junit/src/com/sleepycat/db/test/PartialGetTest.java new file mode 100644 index 00000000..35d97721 --- /dev/null +++ b/test/java/junit/src/com/sleepycat/db/test/PartialGetTest.java @@ -0,0 +1,264 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. + * + */ + +package com.sleepycat.db.test; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import com.sleepycat.db.*; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; + +import com.sleepycat.db.test.TestUtils; +public class PartialGetTest { + public static final String PARTIALGETTEST_DBNAME = "partialgettest.db"; + public static final byte[] data_64chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890<>".getBytes(); + @BeforeClass public static void ClassInit() { + TestUtils.loadConfig(null); + TestUtils.check_file_removed(TestUtils.getDBFileName(PARTIALGETTEST_DBNAME), true, true); + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(PARTIALGETTEST_DBNAME)); + } + + @AfterClass public static void ClassShutdown() { + TestUtils.check_file_removed(TestUtils.getDBFileName(PARTIALGETTEST_DBNAME), true, true); + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(PARTIALGETTEST_DBNAME)); + } + + @Before public void PerTestInit() + throws Exception { + } + + @After public void PerTestShutdown() + throws Exception { + TestUtils.check_file_removed(TestUtils.getDBFileName(PARTIALGETTEST_DBNAME), true, true); + } + /* + * Test case implementations. + * To disable a test mark it with @Ignore + * To set a timeout(ms) notate like: @Test(timeout=1000) + * To indicate an expected exception notate like: (expected=Exception) + */ + + /* + * Simple partial gets on a record which is on a single page. + */ + @Test public void test1() + throws DatabaseException, FileNotFoundException + { + DatabaseEntry key = new DatabaseEntry("key".getBytes()); + Database db = setupDb1(key, data_64chars); + + StringEntry partialData = new StringEntry(); + partialData.setPartial(true); + partialData.setPartial(0, 12, true); + + if (db.get(null, key, partialData, LockMode.DEFAULT) != + OperationStatus.SUCCESS) + fail("Failed doing partial retrieval, first part of entry on single page."); + // Validate the data. + if (!MatchData(data_64chars, partialData.getString(), 12)) + fail("Data mismatch from partial get."); + + partialData.setPartial(12, 12, true); + if (db.get(null, key, partialData, LockMode.DEFAULT) != + OperationStatus.SUCCESS) + fail("Failed doing partial retrieval, second part of entry on single page."); + // Validate the data. + if (!MatchData(new String(data_64chars, 12, 12), partialData.getString(), 12)) + fail("Data mismatch from partial get."); + + db.close(false); + } + + /* + * Retrieve entry using different DB_DBT_alloc flags. + * Verify results. + */ + @Test public void test2() + throws DatabaseException, FileNotFoundException + { + DatabaseEntry key = new DatabaseEntry("key".getBytes()); + Database db = setupDb1(key, data_64chars); + StringEntry partialData = new StringEntry(); + partialData.setPartial(true); + partialData.setPartial(0, 12, true); + + if (db.get(null, key, partialData, LockMode.DEFAULT) != + OperationStatus.SUCCESS) + fail("Failed doing partial retrieval."); + // Validate the data. + if (!MatchData(data_64chars, partialData.getString(), 12)) + fail("Data mismatch from partial get."); + + partialData.setReuseBuffer(true); + if (db.get(null, key, partialData, LockMode.DEFAULT) != + OperationStatus.SUCCESS) + if (!MatchData(data_64chars, partialData.getString(), 12)) + fail("Data mismatch from partial get."); + + partialData.setReuseBuffer(false); + partialData.setUserBuffer(64, true); + partialData.setData(new byte[64]); + if (db.get(null, key, partialData, LockMode.DEFAULT) != + OperationStatus.SUCCESS) + if (!MatchData(data_64chars, partialData.getString(), 12)) + fail("Data mismatch from partial get."); + + partialData.setPartial(12, 12, true); + if (db.get(null, key, partialData, LockMode.DEFAULT) != + OperationStatus.SUCCESS) + fail("Failed doing partial retrieval."); + // Validate the data. + if (!MatchData(new String(data_64chars, 12, 12), partialData.getString(), 12)) + fail("Data mismatch from partial get."); + + db.close(false); + } + + /* Retrieve entry that spans multiple pages. */ + + @Test public void test3() + throws DatabaseException, FileNotFoundException + { + DatabaseEntry key = new DatabaseEntry("key".getBytes()); + StringBuffer sb = new StringBuffer(1024*100); + for(int i = 0; i < 1024; i++) { + sb.append("abcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*()_+-="); + sb.append("abcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*()_+-="); + } + Database db = setupDb1(key, sb.toString().getBytes()); + + StringEntry partialData = new StringEntry(); + partialData.setPartial(true); + partialData.setPartial(0, 12, true); + + if (db.get(null, key, partialData, LockMode.DEFAULT) != + OperationStatus.SUCCESS) + fail("Failed doing partial retrieval."); + // Validate the data. + if (!MatchData(data_64chars, partialData.getString(), 12)) + fail("Data mismatch from partial get."); + + // retrieve a chunk larger than a page size, starting at offset 0. + partialData.setPartial(0, 2048, true); + if (db.get(null, key, partialData, LockMode.DEFAULT) != + OperationStatus.SUCCESS) + fail("Failed doing partial retrieval."); + // Validate the data. + if (!MatchData(sb.substring(0, 2048), partialData.getString(), 2048)) + fail("Data mismatch from partial get."); + + // retrieve a chunk larger than a page size, starting at offset greater than 0. + partialData.setPartial(10, 2048, true); + if (db.get(null, key, partialData, LockMode.DEFAULT) != + OperationStatus.SUCCESS) + fail("Failed doing partial retrieval."); + // Validate the data. + if (!MatchData(sb.substring(10, 2048+10), partialData.getString(), 12)) + fail("Data mismatch from partial get."); + + db.close(false); + } + + /* + * Test partial retrieval using a cursor. + */ + @Test public void test4() + throws DatabaseException, FileNotFoundException + { + } + + /* + * Test partial retrieval using different DB types. + */ + @Test public void test5() + throws DatabaseException, FileNotFoundException + { + } + + /* + * Test partial retrieval . + */ + @Test public void test6() + throws DatabaseException, FileNotFoundException + { + } + + /* + * Helper methods and classes follow. + */ + + private Database setupDb1(DatabaseEntry key, byte[] dataData) + throws DatabaseException, FileNotFoundException + { + DatabaseConfig dbConfig = new DatabaseConfig(); + dbConfig.setErrorStream(TestUtils.getErrorStream()); + dbConfig.setErrorPrefix("PartialGetTest"); + dbConfig.setType(DatabaseType.BTREE); + dbConfig.setPageSize(1024); + dbConfig.setAllowCreate(true); + Database db = new Database(TestUtils.getDBFileName(PARTIALGETTEST_DBNAME), null, dbConfig); + + DatabaseEntry data = new DatabaseEntry(dataData); + + if(db.putNoOverwrite(null, key, data) != OperationStatus.SUCCESS) + TestUtils.ERR("Failed to create standard entry in database."); + + return db; + } + + /* Save converting String to do data comparisons. */ + private boolean MatchData(byte[] data1, byte[] data2, int len) + { + return MatchData(new String(data1), new String(data2), len); + } + private boolean MatchData(String data1, byte[] data2, int len) + { + return MatchData(data1, new String(data2), len); + } + private boolean MatchData(byte[] data1, String data2, int len) + { + return MatchData(new String(data1), data2, len); + } + private boolean MatchData(String data1, String data2, int len) + { + if(data1.length() < len || data2.length() < len) + return false; + TestUtils.DEBUGOUT(0, "data1: " +data1.substring(0, 12)); + TestUtils.DEBUGOUT(0, "data2: " +data2.substring(0, 12)); + return data1.regionMatches(0, data2, 0, len); + } + + static /*inner*/ + class StringEntry extends DatabaseEntry { + StringEntry() { + } + + StringEntry (String value) { + setString(value); + } + + void setString(String value) { + byte[] data = value.getBytes(); + setData(data); + setSize(data.length); + } + + String getString() { + return new String(getData(), getOffset(), getSize()); + } + } +} diff --git a/test/java/junit/src/com/sleepycat/db/test/PriorityTest.java b/test/java/junit/src/com/sleepycat/db/test/PriorityTest.java new file mode 100644 index 00000000..8f8d7cf4 --- /dev/null +++ b/test/java/junit/src/com/sleepycat/db/test/PriorityTest.java @@ -0,0 +1,91 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. + * + */ + + +package com.sleepycat.db.test; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import com.sleepycat.db.*; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; + +import com.sleepycat.db.test.TestUtils; +public class PriorityTest { + public static final String PRIORITYTEST_DBNAME = "prioritytest.db"; + @BeforeClass public static void ClassInit() { + TestUtils.loadConfig(null); + TestUtils.check_file_removed(TestUtils.getDBFileName(PRIORITYTEST_DBNAME), true, true); + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(PRIORITYTEST_DBNAME)); + } + + @AfterClass public static void ClassShutdown() { + TestUtils.check_file_removed(TestUtils.getDBFileName(PRIORITYTEST_DBNAME), true, true); + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(PRIORITYTEST_DBNAME)); + } + + @Before public void PerTestInit() + throws Exception { + } + + @After public void PerTestShutdown() + throws Exception { + } + /* + * Test case implementations. + * To disable a test mark it with @Ignore + * To set a timeout(ms) notate like: @Test(timeout=1000) + * To indicate an expected exception notate like: (expected=Exception) + */ + + @Test public void test1() + throws DatabaseException, FileNotFoundException + { + EnvironmentConfig envc = new EnvironmentConfig(); + envc.setAllowCreate(true); + envc.setInitializeCache(true); + envc.setInitializeLocking(true); + envc.setInitializeLogging(true); + envc.setTransactional(true); + Environment dbEnv = new Environment(TestUtils.BASETEST_DBFILE, envc); + + DatabaseConfig dbConfig = new DatabaseConfig(); + dbConfig.setErrorStream(TestUtils.getErrorStream()); + dbConfig.setErrorPrefix("TxnPriorityTest"); + dbConfig.setType(DatabaseType.BTREE); + dbConfig.setAllowCreate(true); + dbConfig.setTransactional(true); + + Transaction txn = dbEnv.beginTransaction(null, null); + txn.setPriority(555); + + Database db = dbEnv.openDatabase(txn, PRIORITYTEST_DBNAME, null, dbConfig); + assertEquals(txn.getPriority(), 555); + TransactionStats st = dbEnv.getTransactionStats(null); + TransactionStats.Active[] active = st.getTxnarray(); + assertEquals(active.length, 1); + assertEquals(active[0].getPriority(), txn.getPriority()); + + txn.commit(); + db.close(); + + int lockerid = dbEnv.createLockerID(); + dbEnv.setLockerPriority(lockerid, 558); + assertEquals(dbEnv.getLockerPriority(lockerid), 558); + dbEnv.freeLockerID(lockerid); + + dbEnv.close(); + } +} diff --git a/test/java/junit/src/com/sleepycat/db/test/RepmgrConfigTest.java b/test/java/junit/src/com/sleepycat/db/test/RepmgrConfigTest.java new file mode 100644 index 00000000..f8d8b789 --- /dev/null +++ b/test/java/junit/src/com/sleepycat/db/test/RepmgrConfigTest.java @@ -0,0 +1,352 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. + * + */ + + +/* + * A test case that brings up the replication + * manager infrastructure as master. Then shut + * the master down cleanly. + * This case does not have any replication clients + * or even update the underlying DB. + */ + +package com.sleepycat.db.test; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Ignore; +import org.junit.Test; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import junit.framework.JUnit4TestAdapter; + +import java.io.File; +import java.io.FileNotFoundException; + +import com.sleepycat.db.*; + +public class RepmgrConfigTest extends EventHandlerAdapter +{ + private class ConfigOptions { + public ConfigOptions( + boolean txnSync, + boolean initializeReplication, + boolean verboseReplication, + boolean setLocalSiteEnable, + boolean setReplicationInMemory, + boolean setReplicationPriority, + int replicationPriority, + boolean setValidEventHandler, + boolean setAckPolicy, + ReplicationManagerAckPolicy ackPolicyToSet, + int nThreadsToStart, + boolean validStartPolicy, + int requestMin, + int requestMax, + boolean validPolicy + ) + { + this.txnSync = txnSync; + this.initializeReplication = initializeReplication; + this.verboseReplication = verboseReplication; + this.setLocalSiteEnable = setLocalSiteEnable; + this.setReplicationPriority = setReplicationPriority; + this.setReplicationInMemory = setReplicationInMemory; + this.replicationPriority = replicationPriority; + this.setValidEventHandler = setValidEventHandler; + this.setAckPolicy = setAckPolicy; + this.ackPolicyToSet = ackPolicyToSet; + this.nThreadsToStart = nThreadsToStart; + this.validStartPolicy = validStartPolicy; + this.validPolicy = validPolicy; + this.requestMin = requestMin; + this.requestMax = requestMax; + } + + boolean txnSync; + boolean initializeReplication; + boolean verboseReplication; + boolean setLocalSiteEnable; + boolean setValidEventHandler; + boolean setReplicationInMemory; + boolean setReplicationPriority; + int replicationPriority; + boolean setAckPolicy; + ReplicationManagerAckPolicy ackPolicyToSet; + int nThreadsToStart; + boolean validStartPolicy; + int requestMin; + int requestMax; + + // should this set of options work or not? + boolean validPolicy; + } + + static String address = "localhost"; + static int port = 4242; + static int priority = 100; + static String homedirName = ""; + + ConfigOptions[] optionVariations = + { + new ConfigOptions(true, true, false, true, false, true, 50, true, true, ReplicationManagerAckPolicy.ALL, 1, true, 3, 9, true ), //0: + new ConfigOptions(false, true, false, true, false, true, 50, true, true, ReplicationManagerAckPolicy.ALL, 1, true, 3, 9, true ), //1: disable txnSync + new ConfigOptions(true, false, false, true, false, true, 50, true, true, ReplicationManagerAckPolicy.ALL, 1, true, 3, 9, false ), //2: don't call initRep + new ConfigOptions(true, true, true, true, false, true, 50, true, true, ReplicationManagerAckPolicy.ALL, 1, true, 3, 9, true ), //3: enable verbose rep + new ConfigOptions(true, true, false, false, false, true, 50, true, true, ReplicationManagerAckPolicy.ALL, 1, true, 3, 9, false ), //4: don't set a local site + new ConfigOptions(true, true, false, true, false, false, 50, true, true, ReplicationManagerAckPolicy.ALL, 1, true, 3, 9, true ), //5: don't assign priority explicitly + new ConfigOptions(true, true, false, true, false, true, -1, true, true, ReplicationManagerAckPolicy.ALL, 1, true, 3, 9, true ), //6: ??assign an invalid priority. + new ConfigOptions(true, true, false, true, false, true, 50, false, true, ReplicationManagerAckPolicy.ALL, 1, true, 3, 9, false ), //7: don't set the event handler. + new ConfigOptions(true, true, false, true, false, true, 50, true, false, ReplicationManagerAckPolicy.ALL, 1, true, 3, 9, true ), //8: ?? don't set ack policy + new ConfigOptions(true, true, false, true, false, true, 50, true, true, ReplicationManagerAckPolicy.ALL_PEERS, 1, true, 3, 9, true ), //9: + new ConfigOptions(true, true, false, true, false, true, 50, true, true, ReplicationManagerAckPolicy.ALL_AVAILABLE, 1, true, 3, 9, true ), //10: + new ConfigOptions(true, true, false, true, false, true, 50, true, true, ReplicationManagerAckPolicy.NONE, 1, true, 3, 9, true ), //11: + new ConfigOptions(true, true, false, true, false, true, 50, true, true, ReplicationManagerAckPolicy.ONE, 1, true, 3, 9, true ), //12: + new ConfigOptions(true, true, false, true, false, true, 50, true, true, ReplicationManagerAckPolicy.ONE_PEER, 1, true, 3, 9, true ), //13: + new ConfigOptions(true, true, false, true, false, true, 50, true, true, null, 1, true, 3, 9, false ), //14: set an invalid ack policy + new ConfigOptions(true, true, false, true, false, true, 50, true, true, ReplicationManagerAckPolicy.ALL, 5, true, 3, 9, true), //15: set a large nthreads value, no harm + new ConfigOptions(true, true, false, true, false, true, 50, true, true, ReplicationManagerAckPolicy.ALL, 0, true, 3, 9, false ), //16: set an invalid nthreads + new ConfigOptions(true, true, false, true, false, true, 50, true, true, ReplicationManagerAckPolicy.ALL, 1, false, 3, 9, false ), //17: dont set a valid start policy. + new ConfigOptions(true, true, false, true, false, true, 50, true, true, ReplicationManagerAckPolicy.ALL, 1, true, 0, 9, false ), //18: set requestMin as 0 + new ConfigOptions(true, true, false, true, false, true, 50, true, true, ReplicationManagerAckPolicy.ALL, 1, true, 9, 3, false ), //19: set requestMax < requestMin + new ConfigOptions(true, true, false, true, true, true, 50, true, true, ReplicationManagerAckPolicy.ALL, 1, true, 3, 9, true ), //20: set replication in memory. + }; + + File homedir; + EnvironmentConfig envConfig; + + @BeforeClass public static void ClassInit() { + TestUtils.loadConfig(null); + } + + @AfterClass public static void ClassShutdown() { + } + + @Before public void PerTestInit() + { + homedirName = TestUtils.BASETEST_DBDIR + "/TESTDIR"; + TestUtils.removeDir(homedirName); + try { + homedir = new File(homedirName); + homedir.mkdir(); + } catch (Exception e) { + TestUtils.DEBUGOUT(2, "Warning: initialization had a problem creating a clean directory.\n" + e); + } + try { + homedir = new File(homedirName); + } catch (NullPointerException npe) { + // can't really happen :) + } + envConfig = new EnvironmentConfig(); + envConfig.setErrorStream(TestUtils.getErrorStream()); + envConfig.setErrorPrefix("RepmgrConfigTest test"); + envConfig.setAllowCreate(true); + envConfig.setRunRecovery(true); + envConfig.setThreaded(true); + envConfig.setInitializeLocking(true); + envConfig.setInitializeLogging(true); + envConfig.setInitializeCache(true); + envConfig.setTransactional(true); + + // Linux seems to have problems cleaning up its sockets. + // so start each test at a new address. + ++port; + } + + @After public void PerTestShutdown() + throws Exception { + TestUtils.removeDir(homedirName); + } + + @Test (timeout=4000) public void TestOptions0() + { + assertTrue(runTestWithOptions(optionVariations[0])); + } + @Test (timeout=4000) public void TestOptions1() + { + assertTrue(runTestWithOptions(optionVariations[1])); + } + @Test (timeout=4000) public void TestOptions2() + { + assertTrue(runTestWithOptions(optionVariations[2])); + } + @Test (timeout=4000) public void TestOptions3() + { + assertTrue(runTestWithOptions(optionVariations[3])); + } + @Test (timeout=4000) public void TestOptions4() + { + assertTrue(runTestWithOptions(optionVariations[4])); + } + @Test (timeout=4000) public void TestOptions5() + { + assertTrue(runTestWithOptions(optionVariations[5])); + } + @Test (timeout=4000) public void TestOptions6() + { + assertTrue(runTestWithOptions(optionVariations[6])); + } + @Ignore("Currently failing") @Test (timeout=4000) public void TestOptions7() + { + assertTrue(runTestWithOptions(optionVariations[7])); + } + @Test (timeout=4000) public void TestOptions8() + { + assertTrue(runTestWithOptions(optionVariations[8])); + } + @Test (timeout=4000) public void TestOptions9() + { + assertTrue(runTestWithOptions(optionVariations[9])); + } + @Test (timeout=4000) public void TestOptions10() + { + assertTrue(runTestWithOptions(optionVariations[10])); + } + @Test (timeout=4000) public void TestOptions11() + { + assertTrue(runTestWithOptions(optionVariations[11])); + } + @Test (timeout=4000) public void TestOptions12() + { + assertTrue(runTestWithOptions(optionVariations[12])); + } + @Test (timeout=4000) public void TestOptions13() + { + assertTrue(runTestWithOptions(optionVariations[13])); + } + @Test (timeout=4000) public void TestOptions14() + { + assertTrue(runTestWithOptions(optionVariations[14])); + } + @Test (timeout=4000) public void TestOptions15() + { + assertTrue(runTestWithOptions(optionVariations[15])); + } + @Test (timeout=4000) public void TestOptions16() + { + assertTrue(runTestWithOptions(optionVariations[16])); + } + @Test (timeout=4000) public void TestOptions17() + { + assertTrue(runTestWithOptions(optionVariations[17])); + } + @Test (timeout=4000) public void TestOptions18() + { + assertTrue(runTestWithOptions(optionVariations[18])); + } + @Test (timeout=4000) public void TestOptions19() + { + assertTrue(runTestWithOptions(optionVariations[19])); + } + + // returns true if failure matches options failure spec. + boolean runTestWithOptions(ConfigOptions opts) + { + boolean retval = true; + boolean gotexcept = false; + Environment dbenv = null; + ReplicationManagerSiteConfig localConfig = null; + try { + envConfig.setTxnNoSync(opts.txnSync); + if (opts.initializeReplication) + envConfig.setInitializeReplication(true); + if (opts.verboseReplication) + envConfig.setVerboseReplication(false); + + if (opts.setLocalSiteEnable) { + localConfig = new ReplicationManagerSiteConfig(address, port); + localConfig.setLocalSite(true); + envConfig.addReplicationManagerSite(localConfig); + } + if (opts.setReplicationInMemory) + envConfig.setReplicationInMemory(true); + if (opts.setReplicationPriority) + envConfig.setReplicationPriority(opts.replicationPriority); + if (opts.setValidEventHandler) + envConfig.setEventHandler(this); + + if (opts.setAckPolicy) + envConfig.setReplicationManagerAckPolicy(opts.ackPolicyToSet); + + envConfig.setReplicationRequestMin(opts.requestMin); + envConfig.setReplicationRequestMax(opts.requestMax); + + try { + dbenv = new Environment(homedir, envConfig); + // Start replication manager + if (opts.validStartPolicy) + dbenv.replicationManagerStart(opts.nThreadsToStart, ReplicationManagerStartPolicy.REP_MASTER); + else + dbenv.replicationManagerStart(opts.nThreadsToStart, null); + + ReplicationManagerSite repmgrSite = dbenv.getReplicationManagerSite(address, port); + } catch(FileNotFoundException e) { + TestUtils.DEBUGOUT(3, "Unexpected FNFE in standard environment creation." + e); + gotexcept = true; + retval = false; // never expect a FNFE + } catch(DatabaseException dbe) { + gotexcept = true; + if (opts.validPolicy) + TestUtils.DEBUGOUT(3, "Unexpected DB exception from Environment create." + dbe); + } catch(IllegalArgumentException iae){ + gotexcept = true; + if (opts.validPolicy) + TestUtils.DEBUGOUT(3, "Unexpected DB exception from setRepRequest." + iae); + } + } catch (IllegalArgumentException iae) { + gotexcept = true; + if (opts.validPolicy) + TestUtils.DEBUGOUT(3, "Unexpected IllegalArgumentException." + iae); + } catch (AssertionError ae) { + gotexcept = true; + if (opts.validPolicy) + TestUtils.DEBUGOUT(3, "Unexpected AssertionError." + ae); + } catch (NullPointerException npe) { + gotexcept = true; + if (opts.validPolicy) + TestUtils.DEBUGOUT(3, "Unexpected NullPointerException." + npe); + } + + if (dbenv != null) { + try { + java.lang.Thread.sleep(1000); + }catch(InterruptedException ie) {} + try { + dbenv.close(); + Environment.remove(homedir, true, envConfig); + } catch(FileNotFoundException fnfe) { + gotexcept = true; + retval = false; + } catch(DatabaseException dbe) { + TestUtils.DEBUGOUT(3, "Unexpected database exception came during shutdown." + dbe); + gotexcept = true; // never expect a shutdown failure. + } + } + if (retval) { + if (gotexcept == opts.validPolicy) + retval = false; + } + return retval; + } + + /* + * TODO: Maybe move this into a general TestEventHandler? + */ + public void handleRepMasterEvent() { + TestUtils.DEBUGOUT(1, "Got a REP_MASTER message"); + } + + public void handleRepClientEvent() { + TestUtils.DEBUGOUT(1, "Got a REP_CLIENT message"); + } + + public void handleRepNewMasterEvent() { + TestUtils.DEBUGOUT(1, "Got a REP_NEW_MASTER message"); + } +} diff --git a/test/java/junit/src/com/sleepycat/db/test/RepmgrElectionTest.java b/test/java/junit/src/com/sleepycat/db/test/RepmgrElectionTest.java new file mode 100644 index 00000000..e2bf6a3e --- /dev/null +++ b/test/java/junit/src/com/sleepycat/db/test/RepmgrElectionTest.java @@ -0,0 +1,244 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. + */ + +package com.sleepycat.db.test; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Test; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import java.io.File; +import java.io.FileNotFoundException; +import java.util.Vector; + +import com.sleepycat.db.*; + +public class RepmgrElectionTest extends EventHandlerAdapter +{ + static String address = "localhost"; + static int basePort = 4242; + static String baseDirName = ""; + File homedir; + EnvironmentConfig envConfig; + Environment dbenv; + int masterIndex = -1; + int maxLoopWait = 30; + + @BeforeClass public static void ClassInit() { + TestUtils.loadConfig(null); + baseDirName = TestUtils.BASETEST_DBDIR + "/TESTDIR"; + } + + @AfterClass public static void ClassShutdown() { + } + + @Before public void PerTestInit() + throws Exception { + } + + @After public void PerTestShutdown() + throws Exception { + for(int j = 0; j < NUM_WORKER_SITES; j++) { + TestUtils.removeDir(baseDirName + j); + } + } + + private static boolean lastSiteStarted = false; + private static int NUM_WORKER_SITES = 5; + @Test public void startConductor() + { + Vector<RepmgrElectionTest> workers = + new Vector<RepmgrElectionTest>(NUM_WORKER_SITES); + + // Start all worker sites. + for (int i = 0; i < NUM_WORKER_SITES; i++) { + RepmgrElectionTest worker; + worker = new RepmgrElectionTest(i, i == 0 ? -1 : 0); + worker.run(); + workers.add(worker); + } + + // Ensure that the first site is master. + ReplicationStats rs = null; + try { + rs = workers.elementAt(0).dbenv.getReplicationStats(StatsConfig.DEFAULT); + } catch (DatabaseException dbe) { + fail("Unexpected database exception came from get replication stats." + dbe); + } + + assertTrue(rs.getEnvId() == rs.getMaster()); + + // Stop the master + try { + workers.elementAt(0).dbenv.close(); + workers.elementAt(0).dbenv = null; + workers.elementAt(0).envConfig = null; + } catch(DatabaseException dbe) { + fail("Unexpected database exception came during shutdown." + dbe); + } + + // Ensure the election is completed. + try { + java.lang.Thread.sleep(5000); + } catch (InterruptedException ie) {} // Do nothing if interrupted. + + // Ensure that the site with priority = 75 is selected as new master. + try { + rs = workers.elementAt(1).dbenv.getReplicationStats(StatsConfig.DEFAULT); + } catch (DatabaseException dbe) { + fail("Unexpected database exception came from get replication stats." + dbe); + } + + assertTrue(rs.getEnvId() == rs.getMaster()); + + // Re-start original master using the new master as bootstrap helper. + RepmgrElectionTest rejoin = new RepmgrElectionTest(0, 1); + rejoin.run(); + workers.remove(0); + workers.insertElementAt(rejoin, 0); + + // Close all the sites and remove their environment contents. + for (int i = 0; i < NUM_WORKER_SITES; i++) { + try { + if (workers.elementAt(i).dbenv != null) { + workers.elementAt(i).dbenv.close(); + workers.elementAt(i).dbenv = null; + workers.elementAt(i).envConfig = null; + } + } catch(DatabaseException dbe) { + fail("Unexpected database exception came during shutdown." + dbe); + } + } + } + + /* + * Worker site implementation + */ + private final static int priorities[] = {100, 75, 50, 50, 25}; + private int siteIndex; + public RepmgrElectionTest() { + // needed to comply with JUnit, since there is also another constructor. + } + RepmgrElectionTest(int siteIndex, int masterIndex) { + this.siteIndex = siteIndex; + this.masterIndex = masterIndex; + } + + public void run() { + String homedirName = baseDirName + siteIndex; + TestUtils.removeDir(homedirName); + + try { + homedir = new File(homedirName); + homedir.mkdir(); + } catch (Exception e) { + TestUtils.DEBUGOUT(2, "Warning: initialization had a problem creating a clean directory.\n" + e); + } + try { + homedir = new File(homedirName); + } catch (NullPointerException npe) { + // can't really happen :) + } + + TestUtils.DEBUGOUT(1, "Creating worker: " + siteIndex); + + envConfig = new EnvironmentConfig(); + envConfig.setErrorStream(TestUtils.getErrorStream()); + envConfig.setErrorPrefix("RepmgrElectionTest test("+siteIndex+")"); + envConfig.setAllowCreate(true); + envConfig.setRunRecovery(true); + envConfig.setThreaded(true); + envConfig.setInitializeLocking(true); + envConfig.setInitializeLogging(true); + envConfig.setInitializeCache(true); + envConfig.setTransactional(true); + envConfig.setTxnNoSync(true); + envConfig.setInitializeReplication(true); + envConfig.setVerboseReplication(false); + + ReplicationManagerSiteConfig localConfig = new ReplicationManagerSiteConfig(address, basePort + siteIndex); + localConfig.setLocalSite(true); + envConfig.addReplicationManagerSite(localConfig); + + envConfig.setReplicationPriority(priorities[siteIndex]); + envConfig.setEventHandler(this); + envConfig.setReplicationManagerAckPolicy(ReplicationManagerAckPolicy.ALL); + + if (masterIndex >= 0) { + // If we already have the master, then set it as the bootstrap helper, + // otherwise, set local site as new master. + ReplicationManagerSiteConfig remoteConfig = + new ReplicationManagerSiteConfig(address, basePort + masterIndex); + remoteConfig.setBootstrapHelper(true); + envConfig.addReplicationManagerSite(remoteConfig); + } + + try { + dbenv = new Environment(homedir, envConfig); + + } catch(FileNotFoundException e) { + fail("Unexpected FNFE in standard environment creation." + e); + } catch(DatabaseException dbe) { + fail("Unexpected database exception came from environment create." + dbe); + } + + try { + // If we do not have master, then set local site as new master. + if(masterIndex == -1) + dbenv.replicationManagerStart(3, ReplicationManagerStartPolicy.REP_MASTER); + else + dbenv.replicationManagerStart(3, ReplicationManagerStartPolicy.REP_CLIENT); + } catch(DatabaseException dbe) { + fail("Unexpected database exception came from replicationManagerStart." + dbe); + } + + TestUtils.DEBUGOUT(1, "Started replication site: " + siteIndex); + lastSiteStarted = true; + + try { + java.lang.Thread.sleep(1000 * (1+ siteIndex)); + } catch (InterruptedException ie) {} + + if(masterIndex != -1) { + // Wait for "Start-up done" for each client, then add next client. + ReplicationStats rs = null; + int i = 0; + do { + try { + java.lang.Thread.sleep(2000); + } catch (InterruptedException e) {} + + try { + rs = dbenv.getReplicationStats(StatsConfig.DEFAULT); + } catch (DatabaseException dbe) { + dbe.printStackTrace(); + fail("Unexpected database exception came from getReplicationStats." + dbe); + } + } while (!rs.getStartupComplete() && i++ < maxLoopWait); + assertTrue(rs.getStartupComplete()); + } + } + + /* + * End worker site implementation + */ + public void handleRepMasterEvent() { + TestUtils.DEBUGOUT(1, "Got a REP_MASTER message"); + TestUtils.DEBUGOUT(1, "My priority: " + priorities[siteIndex]); + } + + public void handleRepClientEvent() { + TestUtils.DEBUGOUT(1, "Got a REP_CLIENT message"); + } + + public void handleRepNewMasterEvent() { + TestUtils.DEBUGOUT(1, "Got a REP_NEW_MASTER message"); + TestUtils.DEBUGOUT(1, "My priority: " + priorities[siteIndex]); + } +} diff --git a/test/java/junit/src/com/sleepycat/db/test/RepmgrSiteTest.java b/test/java/junit/src/com/sleepycat/db/test/RepmgrSiteTest.java new file mode 100644 index 00000000..2024169d --- /dev/null +++ b/test/java/junit/src/com/sleepycat/db/test/RepmgrSiteTest.java @@ -0,0 +1,341 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. + * + * $Id$ + * + * A test program for Java APIs changes due to group membership.[#19878] + */ +package com.sleepycat.db.test; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import java.io.File; +import com.sleepycat.db.*; + +public class RepmgrSiteTest extends EventHandlerAdapter +{ + static String host = "localhost"; + static String homedirName = ""; + static long port = 30100; + static int maxLoopWait = 30; + + File homedir; + EnvironmentConfig envConfig; + + @BeforeClass public static void ClassInit() { + TestUtils.loadConfig(null); + } + + @AfterClass public static void ClassShutdown() { + } + + @Before public void PerTestInit() + throws Exception { + homedirName = TestUtils.BASETEST_DBDIR + File.separator + "TESTDIR"; + + TestUtils.removeDir(homedirName + File.separator + "client2"); + TestUtils.removeDir(homedirName + File.separator + "client1"); + TestUtils.removeDir(homedirName + File.separator + "master"); + TestUtils.removeDir(homedirName); + + homedir = new File(homedirName); + homedir.mkdir(); + + envConfig = initEnvConfig(); + + port++; + } + + @After public void PerTestShutdown() + throws Exception { + } + + private EnvironmentConfig initEnvConfig() + { + EnvironmentConfig envCon = new EnvironmentConfig(); + envCon.setErrorStream(TestUtils.getErrorStream()); + envCon.setErrorPrefix("RepmgrSiteTest test"); + envCon.setAllowCreate(true); + envCon.setRunRecovery(true); + envCon.setThreaded(true); + envCon.setInitializeLocking(true); + envCon.setInitializeLogging(true); + envCon.setInitializeCache(true); + envCon.setTransactional(true); + envCon.setInitializeReplication(true); + + return envCon; + } + + private boolean waitForStartUpDone(Environment env) throws Exception + { + // Ensure the site reach a status of "start-up done", + // if not, pause and retry status for a max loop times. + ReplicationStats rs = null; + int i = 0; + + do { + java.lang.Thread.sleep(2000); + rs = env.getReplicationStats(StatsConfig.DEFAULT); + } while (!rs.getStartupComplete() && i++ < maxLoopWait); + + return (rs.getStartupComplete()); + } + + @Test public void testNoLocalSite() throws Exception + { + Environment env = new Environment(homedir, envConfig); + assertNull(env.getReplicationManagerLocalSite()); + env.close(); + } + + @Test public void testGroupCreator() throws Exception + { + // Start master via group creator plus REP_ELECTION. + ReplicationManagerSiteConfig mConf = + new ReplicationManagerSiteConfig(host, port); + mConf.setLocalSite(true); + mConf.setGroupCreator(true); + envConfig.addReplicationManagerSite(mConf); + + Environment env = new Environment(homedir, envConfig); + env.replicationManagerStart(4, ReplicationManagerStartPolicy.REP_ELECTION); + + // Ensure the configuration of local site is correct: + // host, port, localsite, group creator. + ReplicationManagerSite dbsite = env.getReplicationManagerLocalSite(); + assertEquals(host, dbsite.getAddress().host); + assertEquals(port, dbsite.getAddress().port); + assertTrue(dbsite.getLocalSite()); + assertTrue(dbsite.getGroupCreator()); + + ReplicationStats rs = env.getReplicationStats(StatsConfig.DEFAULT); + assertEquals(ReplicationStats.REP_MASTER, rs.getStatus()); + + dbsite.close(); + env.close(); + } + + @Test public void testLocalSite() throws Exception + { + // Start master via REP_MASTER flag without group creator. + ReplicationManagerSiteConfig mConf = + new ReplicationManagerSiteConfig(host, port); + mConf.setLocalSite(true); + envConfig.addReplicationManagerSite(mConf); + + Environment env = new Environment(homedir, envConfig); + env.replicationManagerStart(4, ReplicationManagerStartPolicy.REP_MASTER); + + // Ensure the configuration of local site is correct: + // host, port, localsite. + ReplicationManagerSite dbsite = env.getReplicationManagerLocalSite(); + assertEquals(host, dbsite.getAddress().host); + assertEquals(port, dbsite.getAddress().port); + assertTrue(dbsite.getLocalSite()); + assertTrue(!dbsite.getGroupCreator()); + + dbsite.close(); + env.close(); + } + + @Test public void testRepmgrSiteConfig() throws Exception + { + // Start up master. + File mHomeDir = new File(homedirName + File.separator + "master"); + mHomeDir.mkdir(); + ReplicationManagerSiteConfig mConf = + new ReplicationManagerSiteConfig(host, port); + mConf.setLocalSite(true); + mConf.setGroupCreator(true); + envConfig.addReplicationManagerSite(mConf); + + Environment mEnv = new Environment(mHomeDir, envConfig); + // Ensure the configuration of site before repmgr start is correct. + ReplicationManagerSite mSite = + mEnv.getReplicationManagerSite(host, port); + assertEquals(host, mSite.getAddress().host); + assertEquals(port, mSite.getAddress().port); + assertTrue(mSite.getLocalSite()); + assertTrue(mSite.getGroupCreator()); + mSite.close(); + + mEnv.replicationManagerStart(4, ReplicationManagerStartPolicy.REP_MASTER); + long mPort = port; + + // Client 1 starts up with master as its bootstrap helper. + ReplicationManagerSiteConfig hConf = + new ReplicationManagerSiteConfig(host, mPort); + hConf.setBootstrapHelper(true); + assertTrue(hConf.getBootstrapHelper()); + + // Start up client 1. + File cHomeDir1 = new File(homedirName + File.separator + "client1"); + cHomeDir1.mkdir(); + + port++; + ReplicationManagerSiteConfig cConf1 = + new ReplicationManagerSiteConfig(host, port); + cConf1.setLocalSite(true); + long cPort1 = port; + + EnvironmentConfig cEnvConfig1 = initEnvConfig(); + cEnvConfig1.addReplicationManagerSite(cConf1); + cEnvConfig1.addReplicationManagerSite(hConf); + + Environment cEnv1 = new Environment(cHomeDir1, cEnvConfig1); + cEnv1.replicationManagerStart(4, ReplicationManagerStartPolicy.REP_CLIENT); + assertTrue(waitForStartUpDone(cEnv1)); + + // Ensure the configuration of client 1 after repmgr start is correct. + ReplicationManagerSite cSite1 = cEnv1.getReplicationManagerLocalSite(); + assertEquals(host, cSite1.getAddress().host); + assertEquals(cPort1, cSite1.getAddress().port); + assertTrue(cSite1.getLocalSite()); + assertTrue(!cSite1.getBootstrapHelper()); + assertTrue(!cSite1.getPeer()); + cSite1.close(); + + // Ensure the master in client 1's environment has correct configuration. + ReplicationManagerSite mInCEnv1 = + cEnv1.getReplicationManagerSite(host, mPort); + assertEquals(host, mInCEnv1.getAddress().host); + assertEquals(mPort, mInCEnv1.getAddress().port); + assertTrue(!mInCEnv1.getLocalSite()); + assertTrue(mInCEnv1.getBootstrapHelper()); + assertTrue(!mInCEnv1.getPeer()); + mInCEnv1.close(); + + cEnv1.close(); + mEnv.close(); + } + + @Test public void testRepmgrSitebyEid() throws Exception + { + // Get repmgr site by eid + ReplicationManagerSiteConfig lConf = + new ReplicationManagerSiteConfig(host, port); + lConf.setLocalSite(true); + lConf.setGroupCreator(true); + envConfig.addReplicationManagerSite(lConf); + + Environment env = new Environment(homedir, envConfig); + env.replicationManagerStart(4, ReplicationManagerStartPolicy.REP_MASTER); + + ReplicationManagerSite dbsite = env.getReplicationManagerLocalSite(); + assertTrue(dbsite.getLocalSite()); + + // Ensure the get site by eid works well. + ReplicationManagerSite site = + env.getReplicationManagerSite(dbsite.getEid()); + assertEquals(host, site.getAddress().host); + assertEquals(port, site.getAddress().port); + + site.close(); + dbsite.close(); + env.close(); + } + + @Test (expected=IllegalArgumentException.class) + public void testRepmgrSiteClose() throws Exception + { + // Start up master. + ReplicationManagerSiteConfig lConf = + new ReplicationManagerSiteConfig(host, port); + lConf.setLocalSite(true); + lConf.setGroupCreator(true); + envConfig.addReplicationManagerSite(lConf); + + Environment env = new Environment(homedir, envConfig); + env.replicationManagerStart(4, ReplicationManagerStartPolicy.REP_MASTER); + + ReplicationManagerSite dbsite = + env.getReplicationManagerSite(host, port); + dbsite.close(); + + // Ensure the DbSite handle cannot work after close. + dbsite.getLocalSite(); + + env.close(); + } + + @Test public void testRepmgrSiteRemove() throws Exception + { + // Start up master. + File mHomeDir = new File(homedirName + File.separator + "master"); + mHomeDir.mkdir(); + + ReplicationManagerSiteConfig mConf = + new ReplicationManagerSiteConfig(host, port); + mConf.setLocalSite(true); + mConf.setGroupCreator(true); + envConfig.addReplicationManagerSite(mConf); + + Environment mEnv = new Environment(mHomeDir, envConfig); + mEnv.replicationManagerStart(4, ReplicationManagerStartPolicy.REP_MASTER); + long mPort = port; + + // All clients start up with master as bootstrap helper. + ReplicationManagerSiteConfig hConf = + new ReplicationManagerSiteConfig(host, mPort); + hConf.setBootstrapHelper(true); + + // Start up Client 1. + File cHomeDir1 = new File(homedirName + File.separator + "client1"); + cHomeDir1.mkdir(); + + port++; + ReplicationManagerSiteConfig cConf1 = + new ReplicationManagerSiteConfig(host, port); + cConf1.setLocalSite(true); + long cPort1 = port; + + EnvironmentConfig cEnvConfig1 = initEnvConfig(); + cEnvConfig1.addReplicationManagerSite(cConf1); + cEnvConfig1.addReplicationManagerSite(hConf); + Environment cEnv1 = new Environment(cHomeDir1, cEnvConfig1); + cEnv1.replicationManagerStart(4, ReplicationManagerStartPolicy.REP_CLIENT); + assertTrue(waitForStartUpDone(cEnv1)); + + // Start up Client 2. + File cHomeDir2 = new File(homedirName + File.separator + "client2"); + cHomeDir2.mkdir(); + + port++; + ReplicationManagerSiteConfig cConf2 = + new ReplicationManagerSiteConfig(host, port); + cConf2.setLocalSite(true); + long cPort2 = port; + + EnvironmentConfig cEnvConfig2 = initEnvConfig(); + cEnvConfig2.addReplicationManagerSite(cConf2); + cEnvConfig2.addReplicationManagerSite(hConf); + Environment cEnv2 = new Environment(cHomeDir2, cEnvConfig2); + cEnv2.replicationManagerStart(4, ReplicationManagerStartPolicy.REP_CLIENT); + assertTrue(waitForStartUpDone(cEnv2)); + + // Before remove, we have total 3 sites in group. + int nSites = mEnv.getReplicationNumSites(); + assertEquals(3, nSites); + + // Remove client 2 via client 1. + cEnv1.getReplicationManagerSite(host, cPort2).remove(); + + // After remove, master environment has only 1 remote site. + ReplicationManagerSiteInfo[] siteLists2 = + mEnv.getReplicationManagerSiteList(); + assertEquals(1, siteLists2.length); + + cEnv2.close(); + cEnv1.close(); + mEnv.close(); + } +} diff --git a/test/java/junit/src/com/sleepycat/db/test/RepmgrStartupTest.java b/test/java/junit/src/com/sleepycat/db/test/RepmgrStartupTest.java new file mode 100644 index 00000000..2897752e --- /dev/null +++ b/test/java/junit/src/com/sleepycat/db/test/RepmgrStartupTest.java @@ -0,0 +1,217 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. + * + */ + +/* + * A test case that brings up the replication + * manager infrastructure as master. Then shut + * the master down cleanly. + * This case does not have any replication clients + * or even update the underlying DB. + */ + +package com.sleepycat.db.test; + +import com.sleepycat.db.test.TestUtils; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import junit.framework.JUnit4TestAdapter; + +import java.io.File; +import java.io.FileNotFoundException; + +import com.sleepycat.db.*; + +public class RepmgrStartupTest extends EventHandlerAdapter +{ + static String address = "localhost"; + static int port = 4242; + static int priority = 100; + static String homedirName = "TESTDIR"; + File homedir; + EnvironmentConfig envConfig; + Environment dbenv; + + @BeforeClass public static void ClassInit() { + TestUtils.loadConfig(null); + } + + @AfterClass public static void ClassShutdown() { + } + + @Before public void PerTestInit() + { + TestUtils.removeDir(homedirName); + try { + homedir = new File(homedirName); + homedir.mkdir(); + } catch (Exception e) { + TestUtils.DEBUGOUT(2, "Warning: initialization had a problem creating a clean directory.\n" + e); + } + try { + homedir = new File(homedirName); + } catch (NullPointerException npe) { + // can't really happen :) + } + envConfig = new EnvironmentConfig(); + envConfig.setErrorStream(TestUtils.getErrorStream()); + envConfig.setErrorPrefix("RepmgrStartupTest test"); + envConfig.setAllowCreate(true); + envConfig.setRunRecovery(true); + envConfig.setThreaded(true); + envConfig.setInitializeLocking(true); + envConfig.setInitializeLogging(true); + envConfig.setInitializeCache(true); + envConfig.setTransactional(true); + envConfig.setTxnNoSync(true); + envConfig.setInitializeReplication(true); + envConfig.setVerboseReplication(false); + + ReplicationManagerSiteConfig localConfig = + new ReplicationManagerSiteConfig(address, port); + localConfig.setLocalSite(true); + envConfig.addReplicationManagerSite(localConfig); + envConfig.setReplicationPriority(priority); + envConfig.setEventHandler(this); + envConfig.setReplicationManagerAckPolicy(ReplicationManagerAckPolicy.ALL); + + try { + dbenv = new Environment(homedir, envConfig); + } catch(FileNotFoundException e) { + fail("Unexpected FNFE in standard environment creation." + e); + } catch(DatabaseException dbe) { + fail("Unexpected database exception came from environment create." + dbe); + } + } + + @After public void PerTestShutdown() + throws Exception { + try { + File homedir = new File(homedirName); + + if (homedir.exists()) { + // The following will fail if the directory contains sub-dirs. + if (homedir.isDirectory()) { + File[] contents = homedir.listFiles(); + for (int i = 0; i < contents.length; i++) + contents[i].delete(); + } + homedir.delete(); + } + } catch (Exception e) { + TestUtils.DEBUGOUT(2, "Warning: shutdown had a problem cleaning up test directory.\n" + e); + } + } + + @Test (timeout=4000) public void startMaster() + { + try { + // start replication manager + dbenv.replicationManagerStart(3, ReplicationManagerStartPolicy.REP_MASTER); + } catch(DatabaseException dbe) { + fail("Unexpected database exception came from replicationManagerStart." + dbe); + } + try { + java.lang.Thread.sleep(1000); + }catch(InterruptedException ie) {} + + try { + dbenv.close(); + Environment.remove(homedir, false, envConfig); + } catch(FileNotFoundException fnfe) { + } catch(DatabaseException dbe) { + fail("Unexpected database exception came during shutdown." + dbe); + } + } + + @Test (timeout=4000) public void startClient() + { + try { + // For group membership, if we do not set a bootstrap for REP_CLIENT, + // then it is expected to throw a DB_REP_UNAVAIL + dbenv.replicationManagerStart(3, ReplicationManagerStartPolicy.REP_CLIENT); + fail("Expected database exception came from replicationManagerStart."); + } catch(DatabaseException dbe) {} + try { + java.lang.Thread.sleep(1000); + }catch(InterruptedException ie) {} + + try { + dbenv.close(); + Environment.remove(homedir, false, envConfig); + } catch(FileNotFoundException fnfe) { + } catch(DatabaseException dbe) { + fail("Unexpected database exception came during shutdown." + dbe); + } + } + + @Test (timeout=4000) public void startElection() + { + try { + // For group membership, if we do not set a bootstrap for REP_ELECTION, + // then it is expected to throw a DB_REP_UNAVAIL + dbenv.replicationManagerStart(3, ReplicationManagerStartPolicy.REP_ELECTION); + fail("Expected database exception came from replicationManagerStart."); + } catch(DatabaseException dbe) {} + try { + java.lang.Thread.sleep(1000); + }catch(InterruptedException ie) {} + + try { + dbenv.close(); + Environment.remove(homedir, false, envConfig); + } catch(FileNotFoundException fnfe) { + } catch(DatabaseException dbe) { + fail("Unexpected database exception came during shutdown." + dbe); + } + } + + @Test (timeout=15000) public void startMasterWaitBeforeShutdown() + { + try { + // start replication manager + dbenv.replicationManagerStart(3, ReplicationManagerStartPolicy.REP_MASTER); + } catch(DatabaseException dbe) { + fail("Unexpected database exception came from replicationManagerStart." + dbe.toString()); + } + try { + /* + * NOTE! This is a bit alarming - I have seen shutdown failures with the following message: + * + * RepmgrStartupTest test: Waiting for handle count (1) or msg_th (0) to complete replication lockout + * + * When the sleep is over 10 seconds. + */ + java.lang.Thread.sleep(12000); + }catch(InterruptedException ie) {} + + try { + dbenv.close(); + Environment.remove(homedir, false, envConfig); + } catch(FileNotFoundException fnfe) { + } catch(DatabaseException dbe) { + fail("Unexpected database exception came during shutdown." + dbe.toString()); + } + } + + public void handleRepMasterEvent() { + TestUtils.DEBUGOUT(1, "Got a REP_MASTER message"); + } + + public void handleRepClientEvent() { + TestUtils.DEBUGOUT(1, "Got a REP_CLIENT message"); + } + + public void handleRepNewMasterEvent() { + TestUtils.DEBUGOUT(1, "Got a REP_NEW_MASTER message"); + } +} diff --git a/test/java/junit/src/com/sleepycat/db/test/TestUtils.java b/test/java/junit/src/com/sleepycat/db/test/TestUtils.java new file mode 100644 index 00000000..083b1123 --- /dev/null +++ b/test/java/junit/src/com/sleepycat/db/test/TestUtils.java @@ -0,0 +1,246 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. + * + */ + +/* + * Generally useful functions :) + */ + +package com.sleepycat.db.test; + +import static org.junit.Assert.fail; + +import com.sleepycat.db.*; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Properties; + +public class TestUtils +{ + public static boolean config_loaded = false; + public static boolean verbose_flag = false; + public static int debug_level = 2; + + // should be initialized by calling loadEnvVars. Shared between all tests. + public static String BASETEST_DBDIR = ""; + public static File BASETEST_DBFILE = null; // new File(TestUtils.BASETEST_DBDIR); + public static String BASETEST_BACKUPDIR = ""; + public static File BASETEST_BACKUPFILE = null; // new File(TestUtils.BASETEST_BACKUPDIR); + + public static void ERR(String a) + { + System.err.println("FAIL: " + a); + fail(a); + } + + public static void DEBUGOUT(String s) + { + DEBUGOUT(1, s); + } + + public static void DEBUGOUT(int importance, String s) + { + if(importance > debug_level) + System.out.println("DEBUG: " +s); + } + + public static void VERBOSEOUT(String s) + { + if (verbose_flag) + System.out.println(s); + } + + public static void sysexit(int code) + { + System.exit(code); + } + + public static void check_file_removed(String name, boolean fatal, + boolean force_remove_first) + { + File f = new File(name); + if (force_remove_first) { + f.delete(); + } + if (f.exists()) { + if (fatal) + System.out.print("FAIL: "); + DEBUGOUT(1, "File \"" + name + "\" still exists after check_file_removed\n"); + if (fatal) + fail("File \"" + name + "\" still exists after check_file_removed"); + } + } + + + // remove any existing environment or database + public static void removeall(boolean use_db, boolean remove_env, String envpath, String dbname) + { + { + try { + if (remove_env) + Environment.remove(new File(envpath), true, EnvironmentConfig.DEFAULT); + if (use_db) + Database.remove(dbname, null, DatabaseConfig.DEFAULT); + } + catch (DatabaseException dbe) { + DEBUGOUT(1, "TestUtil::removeall exception caught: " + dbe); + } + catch (FileNotFoundException dbe) { + DEBUGOUT(1, "TestUtil::removeall exception caught: " + dbe); + } + } + check_file_removed(dbname, false, !use_db); + if (remove_env) { + for (int i=0; i<8; i++) { + String fname = envpath + "/" + "__db." + i; + check_file_removed(fname, true, !use_db); + } + + // ensure the user knows if there is junk remaining. + // clean out spurious log.00X files + File dir = new File(envpath); + if(dir.isDirectory()) { + String[] remainingfiles = dir.list(); + for(int i = 0; i < remainingfiles.length; i++) { + if(remainingfiles[i].startsWith("log") || remainingfiles[i].endsWith("db2") || + remainingfiles[i].endsWith("log") || remainingfiles[i].startsWith("__db")) { + DEBUGOUT(1, "TestUtils::removeall removing: " +remainingfiles[i]); + check_file_removed(envpath + "/" + remainingfiles[i], false, true); + } else { + if(remainingfiles[i].indexOf("del") == -1) + DEBUGOUT(3, "TestUtils::removeall warning, file: " + remainingfiles[i] + " remains in directory after cleanup."); + } + } + } + } + } + + public static boolean removeDir(String dirname) + { + try { + File deldir = new File(dirname); + + if (!deldir.exists()) { + return true; + } else if(!deldir.isDirectory()) { + return false; + } else { + // The following will fail if the directory contains sub-dirs. + File[] contents = deldir.listFiles(); + for (int i = 0; i < contents.length; i++) + contents[i].delete(); + deldir.delete(); + } + } catch (Exception e) { + TestUtils.DEBUGOUT(4, "Warning: error encountered removing directory.\n" + e); + } + return true; + } + + static public String shownull(Object o) + { + if (o == null) + return "null"; + else + return "not null"; + } + + /* + * The config file is not currently required. + * The only variable that can be set via the + * config file is the base directory for the + * tests to be run in. The default is "data" + * and will be created for the tests. + */ + public static void loadConfig(String envfilename) + { + if(config_loaded) + return; + + String configname = envfilename; + if(envfilename == null) + { + String OSStr = java.lang.System.getProperty("os.name"); + if((OSStr.toLowerCase()).indexOf("windows") != -1) + { + configname = "config_win32"; + } else { + // assume a nix variant. + configname = "config_nix"; + } + } + config_loaded = true; + try { + InputStream in = new FileInputStream(configname); + DEBUGOUT(2, "Opened " + configname + " to read configuration."); + Properties props = new Properties(); + props.load(in); + + String var = props.getProperty("BASETEST_DBDIR"); + if(var != null) + { // Property seems to encase things in ""; + var = var.substring(1); + var = var.substring(0, var.length() -2); + BASETEST_DBDIR = var; + } + DEBUGOUT(2, "BASETEST_DBDIR is: " + BASETEST_DBDIR); + + } catch (Exception e) { + // expected - the config file is optional. + DEBUGOUT(0, "loadEnvVars -- loading of default variables failed. error: " + e); + } + if (BASETEST_DBDIR == "") + BASETEST_DBDIR = "data"; + BASETEST_DBFILE = new File(BASETEST_DBDIR); + if (!BASETEST_DBFILE.exists()) + BASETEST_DBFILE.mkdirs(); + BASETEST_BACKUPDIR = BASETEST_DBDIR + "_bak"; + BASETEST_BACKUPFILE = new File(BASETEST_BACKUPDIR); + if (!BASETEST_BACKUPFILE.exists()) + BASETEST_BACKUPFILE.mkdirs(); + } + + public static String getDBFileName(String dbname) + { + DEBUGOUT(1, "getDBFileName returning: " + BASETEST_DBDIR + "/" + dbname); + return BASETEST_DBDIR + "/" + dbname; + } + + public static String getBackupFileName(String dbname) + { + DEBUGOUT(1, "getBackupFileName returning: " + BASETEST_BACKUPDIR + "/" + dbname); + return BASETEST_BACKUPDIR + "/" + dbname; + } + + public static OutputStream getErrorStream() + { + OutputStream retval = System.err; + try { + File outfile = new File(BASETEST_DBDIR + "/" + "errstream.log"); + if(outfile.exists()) + { + outfile.delete(); + outfile.createNewFile(); + } else { + outfile.createNewFile(); + } + retval = new FileOutputStream(outfile); + } catch (FileNotFoundException fnfe) { + DEBUGOUT(3, "Unable to open error log file. " + fnfe); + } catch (IOException ioe) { + DEBUGOUT(3, "Unable to create error log file. " + ioe); + } + return retval; + } +} diff --git a/test/java/junit/src/com/sleepycat/db/test/VerboseConfigTest.java b/test/java/junit/src/com/sleepycat/db/test/VerboseConfigTest.java new file mode 100644 index 00000000..7e66d556 --- /dev/null +++ b/test/java/junit/src/com/sleepycat/db/test/VerboseConfigTest.java @@ -0,0 +1,108 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. + */ + +package com.sleepycat.db.test; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import com.sleepycat.db.*; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +import com.sleepycat.db.test.TestUtils; +public class VerboseConfigTest { + public static final String VERBOSECONFIGTEST_DBNAME = "verboseconfigtest.db"; + @BeforeClass public static void ClassInit() { + TestUtils.loadConfig(null); + TestUtils.check_file_removed(TestUtils.getDBFileName(VERBOSECONFIGTEST_DBNAME), true, true); + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(VERBOSECONFIGTEST_DBNAME)); + } + + @AfterClass public static void ClassShutdown() { + TestUtils.check_file_removed(TestUtils.getDBFileName(VERBOSECONFIGTEST_DBNAME), true, true); + TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(VERBOSECONFIGTEST_DBNAME)); + } + + @Before public void PerTestInit() + throws Exception { + } + + @After public void PerTestShutdown() + throws Exception { + } + /* + * Test case implementations. + * To disable a test mark it with @Ignore + * To set a timeout(ms) notate like: @Test(timeout=1000) + * To indicate an expected exception notate like: (expected=Exception) + */ + + @Test public void test1() + throws DatabaseException, FileNotFoundException + { + EnvironmentConfig envc = new EnvironmentConfig(); + envc.setAllowCreate(true); + envc.setInitializeCache(true); + envc.setVerbose(VerboseConfig.DEADLOCK, true); + envc.setVerbose(VerboseConfig.FILEOPS, true); + envc.setVerbose(VerboseConfig.FILEOPS_ALL, true); + envc.setVerbose(VerboseConfig.RECOVERY, true); + envc.setVerbose(VerboseConfig.REGISTER, true); + envc.setVerbose(VerboseConfig.REPLICATION, true); + envc.setVerbose(VerboseConfig.WAITSFOR, true); + envc.setMessageStream(new FileOutputStream(new File("messages.txt"))); + Environment db_env = new Environment(TestUtils.BASETEST_DBFILE, envc); + + new File("messages.txt").delete(); + } + + /* + * Tests for old (now deprecated) API. + */ + @Test public void test2() + throws DatabaseException, FileNotFoundException + { + EnvironmentConfig envc = new EnvironmentConfig(); + envc.setAllowCreate(true); + envc.setInitializeCache(true); + envc.setVerboseDeadlock(true); + envc.setVerboseRecovery(true); + envc.setVerboseRegister(true); + envc.setVerboseReplication(true); + envc.setVerboseWaitsFor(true); + envc.setMessageStream(new FileOutputStream(new File("messages.txt"))); + Environment db_env = new Environment(TestUtils.BASETEST_DBFILE, envc); + + new File("messages.txt").delete(); + } + @Test public void test3() throws Exception + { + EnvironmentConfig ec = new EnvironmentConfig(); + ec.setAllowCreate(true); + ec.setInitializeCache(true); + ec.setInitializeLocking(true); + ec.setInitializeLogging(true); + ec.setInitializeReplication(true); + ec.setTransactional(true); + ec.setPrivate(true); + ec.setVerbose(VerboseConfig.REPLICATION_SYSTEM, false); + assertTrue(!ec.getVerbose(VerboseConfig.REPLICATION_SYSTEM)); + Environment env = new Environment(TestUtils.BASETEST_DBFILE, ec); + assertTrue(!env.getConfig().getVerbose(VerboseConfig.REPLICATION_SYSTEM)); + env.close(); + } +} |
