diff options
Diffstat (limited to 'test/scr016')
19 files changed, 3276 insertions, 0 deletions
diff --git a/test/scr016/Makefile b/test/scr016/Makefile new file mode 100644 index 0000000..555464a --- /dev/null +++ b/test/scr016/Makefile @@ -0,0 +1,18 @@ +TESTCLASSES=\ + ./src/com/sleepycat/db/test/*.java + +all: dbtest.jar + +dbtest.jar: classesdir + # Compile the tests and build the test jar + javac -classpath "${DB_JAR}${CP_SEP}${REQUIRED_JARS}" \ + -d ./classes ${TESTCLASSES} + jar cf ./dbtest.jar -C ./classes ./com/sleepycat + +classesdir: + [ -d ./classes ] || (mkdir ./classes) + +clean: + [ -d ./classes ] && rm -rf ./classes + [ -f ./dbtest.jar ] && rm ./dbtest.jar + diff --git a/test/scr016/README b/test/scr016/README new file mode 100644 index 0000000..841d726 --- /dev/null +++ b/test/scr016/README @@ -0,0 +1,14 @@ + +This test suite is designed to test the basic functionality of the core DB Java API. + +To build and run the test suite you need to have JUnit 4 or higher installed, and set in your environment as JUNIT_JAR. + +The script chk.bdb builds and runs all of the test cases currently enabled. + +Each new java source file you created needs to be added to the Makefile. + +The script createnewtest.sh in this directory does just that. run the script with a single parameter which is the name of the new test to create. It will populate the java source file in com/sleepycat/db/test with the basic layout all tests should have. + +The two files config_nix and config_win are used by the test cases to load profile information. For now they only contain a path to the root directory where test output files should be written. +The configuration gets loaded via the TestUtils class. + diff --git a/test/scr016/chk.bdb b/test/scr016/chk.bdb new file mode 100644 index 0000000..88ef64d --- /dev/null +++ b/test/scr016/chk.bdb @@ -0,0 +1,75 @@ +#!/bin/sh - +# +# $Id$ +# +# Run the DB Java API test suite. +# Alternatively supply the class name for an individual test +# case and have that run. + +# NOTES: +# This test requires one JAR not included with the Berkeley DB +# distribution: JUnit (junit.jar) I've been using the 8/31/2002 version +# of JUnit. You can download this JAR from http://jakarta.apache.org/ +# +# JUNIT_JAR=/Users/gburd/Unix/opt/junit/junit.jar + +[ "x$JUNIT_JAR" = "x" ] && { + echo 'FAIL: unset environment variable JUNIT_JAR for junit.jar.' + exit 1 +} + +[ -f $JUNIT_JAR ] || { + echo 'FAIL: JUNIT_JAR not a valid path to the junit.jar.' + exit 1 +} + +case `uname` in +*CYGWIN*) + CP_SEP=";" + d="../../build_windows/Win32/Debug" + DB_LIB_DIR="$d" + PATH="../../build_windows/Win32/Debug:$PATH" + export PATH;; +*) + CP_SEP=":" + d="../../build_unix/" + DB_LIB_DIR="$d/.libs" +esac + +REQUIRED_JARS=$JUNIT_JAR +DB_JAR=$d/db.jar +export DB_JAR +export REQUIRED_JARS +export CP_SEP +export DB_LIB_DIR + +# Build the tests. + +make clean + +[ -f ./dbtest.jar ] || (make dbtest.jar) || { + echo 'FAIL: unable to find or build dbtest.jar' + exit 1 +} + +# Run the tests. + +if [ -n "$1" ] +then + echo "Running: $1" + java -Xcheck:jni -Djava.library.path=$DB_LIB_DIR -cp "$REQUIRED_JARS$CP_SEP$DB_JAR$CP_SEP./dbtest.jar" org.junit.runner.JUnitCore $1 + +else + + for f in `find classes -name "*Test.class"`; do + c=`echo "$f" | sed -e 's/classes\///' -e 's/\.class//' -e 's/\//./g'` + echo "Running: $c" + if java -Xcheck:jni -Djava.library.path=$DB_LIB_DIR -cp "$REQUIRED_JARS$CP_SEP$DB_JAR$CP_SEP./dbtest.jar" org.junit.runner.JUnitCore $c ; then + : + else + echo "FAIL: test program failed" + # exit 1 + fi + done +fi +exit 0 diff --git a/test/scr016/makenewtest.sh b/test/scr016/makenewtest.sh new file mode 100644 index 0000000..70c2803 --- /dev/null +++ b/test/scr016/makenewtest.sh @@ -0,0 +1,117 @@ + +# A script that helps create an empty test shell +# application. +# The only parameter is the name of the class. +# The output file will be in the src/com/sleepycat/db/test +# directory. + + +case $1 in +*Test) +;; +*) + echo "New test case names must end in Test." + exit 1;; +esac + +outdir="src/com/sleepycat/db/test" +if [ ! -d $outdir ] +then + echo "Could not find test source directory. Ensure the script is being run from the right place." + exit 1 +fi + +outname="$outdir/$1.java" + +if [ -f $outname ] +then + echo "A test with that file name exists." + echo -n "Are you sure you want to overwrite the file (yes/no)? " + read got_ok + if [ $got_ok != "yes" ] + then + exit 1 + else + echo "" > $outname + fi +fi + +nameupper=`echo $1 | tr -t [:lower:] [:upper:]` +namelower=`echo $1 | tr -t [:upper:] [:lower:]` + +echo "/*-" >> $outname +echo " * See the file LICENSE for redistribution information." >> $outname +echo " * " >> $outname +echo " * Copyright (c) 2002-2009 Oracle. All rights reserved." >> $outname +echo " *" >> $outname +echo " */" >> $outname +echo "" >> $outname + +echo "" >> $outname + +echo "package com.sleepycat.db.test;" >> $outname +echo "" >> $outname +echo "import org.junit.After;" >> $outname +echo "import org.junit.AfterClass;" >> $outname +echo "import org.junit.Before;" >> $outname +echo "import org.junit.BeforeClass;" >> $outname +echo "import org.junit.Test;" >> $outname +echo "import static org.junit.Assert.assertEquals;" >> $outname +echo "import static org.junit.Assert.fail;" >> $outname +echo "" >> $outname +echo "import com.sleepycat.db.*;" >> $outname +echo "" >> $outname + +# some other likely ones :) +echo "import java.io.File;" >> $outname +echo "import java.io.FileNotFoundException;" >> $outname +echo "import java.io.IOException;" >> $outname + +echo "" >> $outname +echo "import com.sleepycat.db.test.TestUtils;" >> $outname + +echo "public class $1 {" >> $outname + +echo " public static final String ${nameupper}_DBNAME = \"${namelower}.db\";" >> $outname + +echo " @BeforeClass public static void ClassInit() {" >> $outname +echo " TestUtils.loadConfig(null);" >> $outname +echo -n " TestUtils.check_file_removed(TestUtils." >> $outname +echo "getDBFileName(${nameupper}_DBNAME), true, true);" >> $outname +echo -n " TestUtils.removeall(true, true, TestUtils." >> $outname +echo "BASETEST_DBDIR, TestUtils.getDBFileName(${nameupper}_DBNAME));" >> $outname +echo " }" >> $outname + +echo "" >> $outname +echo " @AfterClass public static void ClassShutdown() {" >> $outname +echo -n " TestUtils.check_file_removed(TestUtils." >> $outname +echo "getDBFileName(${nameupper}_DBNAME), true, true);" >> $outname +echo -n " TestUtils.removeall(true, true, TestUtils." >> $outname +echo "BASETEST_DBDIR, TestUtils.getDBFileName(${nameupper}_DBNAME));" >> $outname +echo " }" >> $outname + +echo "" >> $outname +echo " @Before public void PerTestInit()" >> $outname +echo " throws Exception {" >> $outname +echo " }" >> $outname + +echo "" >> $outname +echo " @After public void PerTestShutdown()" >> $outname +echo " throws Exception {" >> $outname +echo " }" >> $outname + +echo " /*" >> $outname +echo " * Test case implementations." >> $outname +echo " * To disable a test mark it with @Ignore" >> $outname +echo " * To set a timeout(ms) notate like: @Test(timeout=1000)" >> $outname +echo " * To indicate an expected exception notate like: $Test(expected=Exception)" >> $outname +echo " */" >> $outname + +echo "" >> $outname +echo " @Test public void test1()" >> $outname +echo " throws DatabaseException, FileNotFoundException" >> $outname +echo " {" >> $outname +echo " }" >> $outname + +echo "}" >> $outname + diff --git a/test/scr016/src/com/sleepycat/db/test/AppendRecnoTest.java b/test/scr016/src/com/sleepycat/db/test/AppendRecnoTest.java new file mode 100644 index 0000000..0ed7455 --- /dev/null +++ b/test/scr016/src/com/sleepycat/db/test/AppendRecnoTest.java @@ -0,0 +1,209 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. 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/scr016/src/com/sleepycat/db/test/AssociateTest.java b/test/scr016/src/com/sleepycat/db/test/AssociateTest.java new file mode 100644 index 0000000..7e07cfe --- /dev/null +++ b/test/scr016/src/com/sleepycat/db/test/AssociateTest.java @@ -0,0 +1,252 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. 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/scr016/src/com/sleepycat/db/test/CallbackTest.java b/test/scr016/src/com/sleepycat/db/test/CallbackTest.java new file mode 100644 index 0000000..420452a --- /dev/null +++ b/test/scr016/src/com/sleepycat/db/test/CallbackTest.java @@ -0,0 +1,159 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. 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/scr016/src/com/sleepycat/db/test/ClosedDbTest.java b/test/scr016/src/com/sleepycat/db/test/ClosedDbTest.java new file mode 100644 index 0000000..bed47e3 --- /dev/null +++ b/test/scr016/src/com/sleepycat/db/test/ClosedDbTest.java @@ -0,0 +1,86 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. 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/scr016/src/com/sleepycat/db/test/DatabaseTest.java b/test/scr016/src/com/sleepycat/db/test/DatabaseTest.java new file mode 100644 index 0000000..1f99876 --- /dev/null +++ b/test/scr016/src/com/sleepycat/db/test/DatabaseTest.java @@ -0,0 +1,377 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. 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.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.LockMode; +import com.sleepycat.db.OperationStatus; + +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 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; + + } + + // 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(null, 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(null, key, data); + + // Acquire a cursor for the table. + Cursor dbcp = db.openCursor(null, 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. + + public TestOptions() + { + this.testmask = 0; + this.user_buffer = 0; + this.successcounter = 0; + this.db_env = 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/scr016/src/com/sleepycat/db/test/EncryptTest.java b/test/scr016/src/com/sleepycat/db/test/EncryptTest.java new file mode 100644 index 0000000..4c387cd --- /dev/null +++ b/test/scr016/src/com/sleepycat/db/test/EncryptTest.java @@ -0,0 +1,138 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. 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/scr016/src/com/sleepycat/db/test/HashCompareTest.java b/test/scr016/src/com/sleepycat/db/test/HashCompareTest.java new file mode 100644 index 0000000..18a8501 --- /dev/null +++ b/test/scr016/src/com/sleepycat/db/test/HashCompareTest.java @@ -0,0 +1,125 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. 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/scr016/src/com/sleepycat/db/test/LogCursorTest.java b/test/scr016/src/com/sleepycat/db/test/LogCursorTest.java new file mode 100644 index 0000000..ad6e624 --- /dev/null +++ b/test/scr016/src/com/sleepycat/db/test/LogCursorTest.java @@ -0,0 +1,101 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. 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/scr016/src/com/sleepycat/db/test/MultipleCursorTest.java b/test/scr016/src/com/sleepycat/db/test/MultipleCursorTest.java new file mode 100644 index 0000000..6b95457 --- /dev/null +++ b/test/scr016/src/com/sleepycat/db/test/MultipleCursorTest.java @@ -0,0 +1,239 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. 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); + } + @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); + } + + /* 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/scr016/src/com/sleepycat/db/test/PartialGetTest.java b/test/scr016/src/com/sleepycat/db/test/PartialGetTest.java new file mode 100644 index 0000000..76ac0c1 --- /dev/null +++ b/test/scr016/src/com/sleepycat/db/test/PartialGetTest.java @@ -0,0 +1,264 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. 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/scr016/src/com/sleepycat/db/test/RepmgrConfigTest.java b/test/scr016/src/com/sleepycat/db/test/RepmgrConfigTest.java new file mode 100644 index 0000000..3cf8b99 --- /dev/null +++ b/test/scr016/src/com/sleepycat/db/test/RepmgrConfigTest.java @@ -0,0 +1,356 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. 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 setReplicationPriority, + int replicationPriority, + boolean setValidEventHandler, + boolean setAckPolicy, + ReplicationManagerAckPolicy ackPolicyToSet, + int nsitesToStart, + boolean validStartPolicy, + int requestMin, + int requestMax, + boolean validPolicy + ) + { + this.txnSync = txnSync; + this.initializeReplication = initializeReplication; + this.verboseReplication = verboseReplication; + this.setLocalSiteEnable = setLocalSiteEnable; + this.setReplicationPriority = setReplicationPriority; + this.replicationPriority = replicationPriority; + this.setValidEventHandler = setValidEventHandler; + this.setAckPolicy = setAckPolicy; + this.ackPolicyToSet = ackPolicyToSet; + this.nsitesToStart = nsitesToStart; + this.validStartPolicy = validStartPolicy; + this.validPolicy = validPolicy; + this.requestMin = requestMin; + this.requestMax = requestMax; + } + + boolean txnSync; + boolean initializeReplication; + boolean verboseReplication; + boolean setLocalSiteEnable; + boolean setValidEventHandler; + boolean setReplicationPriority; + int replicationPriority; + boolean setAckPolicy; + ReplicationManagerAckPolicy ackPolicyToSet; + int nsitesToStart; + 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, true, 50, true, true, ReplicationManagerAckPolicy.ALL, 1, true, 3, 9, true ), //0: + new ConfigOptions(false, true, false, true, true, 50, true, true, ReplicationManagerAckPolicy.ALL, 1, true, 3, 9, true ), //1: disable txnSync + new ConfigOptions(true, false, false, true, true, 50, true, true, ReplicationManagerAckPolicy.ALL, 1, true, 3, 9, false ), //2: don't call initRep + new ConfigOptions(true, true, true, true, true, 50, true, true, ReplicationManagerAckPolicy.ALL, 1, true, 3, 9, true ), //3: enable verbose rep + new ConfigOptions(true, true, 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, 50, true, true, ReplicationManagerAckPolicy.ALL, 1, true, 3, 9, true ), //5: don't assign priority explicitly + new ConfigOptions(true, true, false, true, true, -1, true, true, ReplicationManagerAckPolicy.ALL, 1, true, 3, 9, true ), //6: ??assign an invalid priority. + new ConfigOptions(true, true, false, true, true, 50, false, true, ReplicationManagerAckPolicy.ALL, 1, true, 3, 9, false ), //7: don't set the event handler. + new ConfigOptions(true, true, false, true, true, 50, true, false, ReplicationManagerAckPolicy.ALL, 1, true, 3, 9, true ), //8: ?? don't set ack policy + new ConfigOptions(true, true, false, true, true, 50, true, true, ReplicationManagerAckPolicy.ALL_PEERS, 1, true, 3, 9, true ), //9: + new ConfigOptions(true, true, false, true, true, 50, true, true, ReplicationManagerAckPolicy.NONE, 1, true, 3, 9, true ), //10: + new ConfigOptions(true, true, false, true, true, 50, true, true, ReplicationManagerAckPolicy.ONE, 1, true, 3, 9, true ), //11: + new ConfigOptions(true, true, false, true, true, 50, true, true, ReplicationManagerAckPolicy.ONE_PEER, 1, true, 3, 9, true ), //12: + new ConfigOptions(true, true, false, true, true, 50, true, true, null, 1, true, 3, 9, false ), //13: set an invalid ack policy + new ConfigOptions(true, true, false, true, true, 50, true, true, ReplicationManagerAckPolicy.ALL, -1, true, 3, 9, false ), //14: set nsites negative + new ConfigOptions(true, true, false, true, true, 50, true, true, ReplicationManagerAckPolicy.ALL, 0, true, 3, 9, false ), //15: + new ConfigOptions(true, true, false, true, true, 50, true, true, ReplicationManagerAckPolicy.ALL, 1, false, 3, 9, false ), //16: dont set a valid start policy. + new ConfigOptions(true, true, false, true, true, 50, true, true, ReplicationManagerAckPolicy.ALL, 1, true, 0, 9, false ), //17: set requestMin as 0 + new ConfigOptions(true, true, false, true, true, 50, true, true, ReplicationManagerAckPolicy.ALL, 1, true, 9, 3, false ), //18: set requestMax < requestMin + }; + File homedir; + EnvironmentConfig envConfig; + + @BeforeClass public static void ClassInit() { + TestUtils.loadConfig(null); + homedirName = TestUtils.BASETEST_DBDIR + "/TESTDIR"; + } + + @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("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=3000) public void TestOptions0() + { + assertTrue(runTestWithOptions(optionVariations[0])); + } + @Test (timeout=3000) public void TestOptions1() + { + assertTrue(runTestWithOptions(optionVariations[1])); + } + @Test (timeout=3000) public void TestOptions2() + { + assertTrue(runTestWithOptions(optionVariations[2])); + } + @Test (timeout=3000) public void TestOptions3() + { + assertTrue(runTestWithOptions(optionVariations[3])); + } + @Test (timeout=3000) public void TestOptions4() + { + assertTrue(runTestWithOptions(optionVariations[4])); + } + @Test (timeout=3000) public void TestOptions5() + { + assertTrue(runTestWithOptions(optionVariations[5])); + } + @Test (timeout=3000) public void TestOptions6() + { + assertTrue(runTestWithOptions(optionVariations[6])); + } + @Ignore("Currently failing") @Test (timeout=3000) public void TestOptions7() + { + assertTrue(runTestWithOptions(optionVariations[7])); + } + @Test (timeout=3000) public void TestOptions8() + { + assertTrue(runTestWithOptions(optionVariations[8])); + } + @Test (timeout=3000) public void TestOptions9() + { + assertTrue(runTestWithOptions(optionVariations[9])); + } + @Test (timeout=3000) public void TestOptions10() + { + assertTrue(runTestWithOptions(optionVariations[10])); + } + @Test (timeout=3000) public void TestOptions11() + { + assertTrue(runTestWithOptions(optionVariations[11])); + } + @Test (timeout=3000) public void TestOptions12() + { + assertTrue(runTestWithOptions(optionVariations[12])); + } + @Test (timeout=3000) public void TestOptions13() + { + assertTrue(runTestWithOptions(optionVariations[13])); + } + @Test (timeout=3000) public void TestOptions14() + { + assertTrue(runTestWithOptions(optionVariations[14])); + } + @Test (timeout=3000) public void TestOptions15() + { + assertTrue(runTestWithOptions(optionVariations[15])); + } + @Test (timeout=3000) public void TestOptions16() + { + assertTrue(runTestWithOptions(optionVariations[16])); + } + @Test (timeout=3000) public void TestOptions17() + { + assertTrue(runTestWithOptions(optionVariations[17])); + } + @Test (timeout=3000) public void TestOptions18() + { + assertTrue(runTestWithOptions(optionVariations[18])); + } + + // returns true if failure matches options failure spec. + boolean runTestWithOptions(ConfigOptions opts) + { + boolean retval = true; + boolean gotexcept = false; + Environment dbenv = null; + try { + + envConfig.setTxnNoSync(opts.txnSync); + if (opts.initializeReplication) + envConfig.setInitializeReplication(true); + if (opts.verboseReplication) + envConfig.setVerboseReplication(false); + + if (opts.setLocalSiteEnable) { + ReplicationHostAddress haddr = new ReplicationHostAddress(address, port); + envConfig.setReplicationManagerLocalSite(haddr); + } + 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); + } 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); + } + + if (!gotexcept) { + try { + // start replication manager + if (opts.validStartPolicy) + dbenv.replicationManagerStart(opts.nsitesToStart, ReplicationManagerStartPolicy.REP_MASTER); + else + dbenv.replicationManagerStart(opts.nsitesToStart, null); + } catch(DatabaseException dbe) { + gotexcept = true; + if (opts.validPolicy) + TestUtils.DEBUGOUT(3, "Unexpected database exception came from replicationManagerStart." + dbe); + } catch (IllegalArgumentException iae) { + gotexcept = true; + if (opts.validPolicy) + TestUtils.DEBUGOUT(3, "Unexpected IllegalArgumentException came from replicationManagerStart." + iae); + } catch (NullPointerException npe) { + gotexcept = true; + if (opts.validPolicy) + TestUtils.DEBUGOUT(3, "Unexpected NullPointerException came from replicationManagerStart." + npe); + } catch (AssertionError ae) { + gotexcept = true; + if (opts.validPolicy) + TestUtils.DEBUGOUT(3, "Unexpected AssertionError came from replicationManagerStart." + ae); + } + + } + } 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/scr016/src/com/sleepycat/db/test/RepmgrElectionTest.java b/test/scr016/src/com/sleepycat/db/test/RepmgrElectionTest.java new file mode 100644 index 0000000..3f48fd6 --- /dev/null +++ b/test/scr016/src/com/sleepycat/db/test/RepmgrElectionTest.java @@ -0,0 +1,205 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. 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.assertEquals; +import static org.junit.Assert.fail; +import junit.framework.JUnit4TestAdapter; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.Vector; + +import com.sleepycat.db.*; + +public class RepmgrElectionTest extends EventHandlerAdapter implements Runnable +{ + static String address = "localhost"; + static int basePort = 4242; + static String baseDirName = ""; + File homedir; + EnvironmentConfig envConfig; + Environment dbenv; + + @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_THREADS; j++) + { + String homedirName = baseDirName+j; + TestUtils.removeDir(homedirName); + } + } + + private static boolean lastSiteStarted = false; + private static int NUM_WORKER_THREADS = 5; + @Test(timeout=180000) public void startConductor() + { + Vector<RepmgrElectionTest> workers = new Vector<RepmgrElectionTest>(NUM_WORKER_THREADS); + // start the worker threads + for (int i = 0; i < NUM_WORKER_THREADS; i++) { + RepmgrElectionTest worker = new RepmgrElectionTest(i); + worker.run(); + workers.add(worker); + /* + while (!lastSiteStarted) { + try { + java.lang.Thread.sleep(10); + }catch(InterruptedException e){} + } + lastSiteStarted = false; + */ + } + + // stop the master - ensure the client with the highest priority is elected. + + // re-start original master. Call election ensure correct client is elected + } + + /* + * Worker thread implementation + */ + private final static int priorities[] = {100, 75, 50, 50, 25}; + private int threadNumber; + public RepmgrElectionTest() { + // needed to comply with JUnit, since there is also another constructor. + } + RepmgrElectionTest(int threadNumber) { + this.threadNumber = threadNumber; + } + + public void run() { + EnvironmentConfig envConfig; + Environment dbenv = null; + TestUtils.DEBUGOUT(1, "Creating worker: " + threadNumber); + try { + File homedir = new File(baseDirName + threadNumber); + + 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(); + } + homedir.mkdir(); + } catch (Exception e) { + TestUtils.DEBUGOUT(2, "Warning: initialization had a problem creating a clean directory.\n"+e); + } + try { + homedir = new File(baseDirName+threadNumber); + } catch (NullPointerException npe) { + // can't really happen :) + } + envConfig = new EnvironmentConfig(); + envConfig.setErrorStream(TestUtils.getErrorStream()); + envConfig.setErrorPrefix("RepmgrElectionTest test("+threadNumber+")"); + 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); + + ReplicationHostAddress haddr = new ReplicationHostAddress(address, basePort+threadNumber); + envConfig.setReplicationManagerLocalSite(haddr); + envConfig.setReplicationPriority(priorities[threadNumber]); + 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); + } + + try { + /* + * If all threads are started with REP_ELECTION flag + * The whole system freezes, and I get: + * RepmgrElectionTest test(0): Waiting for handle count (1) or msg_th (0) to complete replication lockout + * Repeated every minute. + */ + envConfig = dbenv.getConfig(); + for(int existingSites = 0; existingSites < threadNumber; existingSites++) + { + /* + * This causes warnings to be produced - it seems only + * able to make a connection to the master site, not other + * client sites. + * The documentation and code lead me to believe this is not + * as expected - so leaving in here for now. + */ + ReplicationHostAddress host = new ReplicationHostAddress( + address, basePort+existingSites); + envConfig.replicationManagerAddRemoteSite(host, false); + } + dbenv.setConfig(envConfig); + if(threadNumber == 0) + dbenv.replicationManagerStart(NUM_WORKER_THREADS, ReplicationManagerStartPolicy.REP_MASTER); + else + dbenv.replicationManagerStart(NUM_WORKER_THREADS, ReplicationManagerStartPolicy.REP_CLIENT); + } catch(DatabaseException dbe) { + fail("Unexpected database exception came from replicationManagerStart." + dbe); + } + TestUtils.DEBUGOUT(1, "Started replication site: " + threadNumber); + lastSiteStarted = true; + try { + java.lang.Thread.sleep(10000); + }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); + } + } + + /* + * End worker thread implementation + */ + public void handleRepMasterEvent() { + TestUtils.DEBUGOUT(1, "Got a REP_MASTER message"); + TestUtils.DEBUGOUT(1, "My priority: " + priorities[threadNumber]); + } + + 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[threadNumber]); + } +} diff --git a/test/scr016/src/com/sleepycat/db/test/RepmgrStartupTest.java b/test/scr016/src/com/sleepycat/db/test/RepmgrStartupTest.java new file mode 100644 index 0000000..e02fdb7 --- /dev/null +++ b/test/scr016/src/com/sleepycat/db/test/RepmgrStartupTest.java @@ -0,0 +1,216 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. 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); + + ReplicationHostAddress haddr = new ReplicationHostAddress(address, port); + envConfig.setReplicationManagerLocalSite(haddr); + 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=3000) 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=3000) public void startClient() + { + try { + // start replication manager + dbenv.replicationManagerStart(3, ReplicationManagerStartPolicy.REP_CLIENT); + } 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=3000) public void startElection() + { + try { + // start replication manager + dbenv.replicationManagerStart(3, ReplicationManagerStartPolicy.REP_ELECTION); + } 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=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/scr016/src/com/sleepycat/db/test/TestUtils.java b/test/scr016/src/com/sleepycat/db/test/TestUtils.java new file mode 100644 index 0000000..140371a --- /dev/null +++ b/test/scr016/src/com/sleepycat/db/test/TestUtils.java @@ -0,0 +1,234 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. 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 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(); + } + + public static String getDBFileName(String dbname) + { + DEBUGOUT(1, "getDBFileName returning: " + BASETEST_DBDIR + "/" + dbname); + return BASETEST_DBDIR + "/" + 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/scr016/src/com/sleepycat/db/test/VerboseConfigTest.java b/test/scr016/src/com/sleepycat/db/test/VerboseConfigTest.java new file mode 100644 index 0000000..8438a40 --- /dev/null +++ b/test/scr016/src/com/sleepycat/db/test/VerboseConfigTest.java @@ -0,0 +1,91 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. 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.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(); + } +} |