[infinispan-commits] Infinispan SVN: r103 - in trunk/cachestore/bdbje/src/test/java/org/infinispan: loader and 1 other directories.
infinispan-commits at lists.jboss.org
infinispan-commits at lists.jboss.org
Wed Apr 8 13:45:10 EDT 2009
Author: galder.zamarreno at jboss.com
Date: 2009-04-08 13:45:09 -0400 (Wed, 08 Apr 2009)
New Revision: 103
Added:
trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/
trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/
trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/BdbjeCacheStoreConfigTest.java
trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/BdbjeCacheStoreIntegrationTest.java
trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/BdbjeCacheStoreTest.java
trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/BdbjeLearningTest.java
trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/BdbjeResourceFactoryTest.java
trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/ModificationsTransactionWorkerTest.java
trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/PreparableTransactionRunnerTest.java
Removed:
trunk/cachestore/bdbje/src/test/java/org/infinispan/bdbje/
Log:
Bdje test classes should be located under org/infinispan/loader/bdje.
Added: trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/BdbjeCacheStoreConfigTest.java
===================================================================
--- trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/BdbjeCacheStoreConfigTest.java (rev 0)
+++ trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/BdbjeCacheStoreConfigTest.java 2009-04-08 17:45:09 UTC (rev 103)
@@ -0,0 +1,81 @@
+package org.infinispan.loader.bdbje;
+
+import org.infinispan.loader.CacheLoaderException;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/**
+ * Unit tests that cover {@link BdbjeCacheStoreConfig }
+ *
+ * @author Adrian Cole
+ * @version $Id$
+ * @since 4.0
+ */
+ at Test(groups = "unit", enabled = true, testName = "loader.bdbje.BdbjeCacheStoreConfigTest")
+public class BdbjeCacheStoreConfigTest {
+
+ private BdbjeCacheStoreConfig config;
+
+ @BeforeMethod
+ public void setUp() throws Exception {
+ config = new BdbjeCacheStoreConfig();
+ }
+
+ @AfterMethod
+ public void tearDown() throws CacheLoaderException {
+ config = null;
+ }
+
+
+ @Test
+ public void testGetClassNameDefault() {
+ assert config.getCacheLoaderClassName().equals(BdbjeCacheStore.class.getName());
+ }
+
+ @Test
+ public void testgetMaxTxRetries() {
+ assert config.getMaxTxRetries() == 5;
+ }
+
+ @Test
+ public void testSetMaxTxRetries() {
+ config.setMaxTxRetries(1);
+ assert config.getMaxTxRetries() == 1;
+ }
+
+ @Test
+ public void testGetLockAcquistionTimeout() {
+ assert config.getLockAcquistionTimeout() == 60 * 1000;
+ }
+
+ @Test
+ public void testSetLockAcquistionTimeoutMicros() {
+ config.setLockAcquistionTimeout(1);
+ assert config.getLockAcquistionTimeout() == 1;
+ }
+
+ @Test
+ public void testGetLocationDefault() {
+ assert config.getLocation().equals("Horizon-BdbjeCacheStore");
+ }
+
+ @Test
+ public void testSetLocation() {
+ config.setLocation("foo");
+ assert config.getLocation().equals("foo");
+ }
+
+ @Test
+ public void testSetCacheDb() {
+ config.setCacheDbName("foo");
+ assert config.getCacheDbName().equals("foo");
+ }
+
+ @Test
+ public void testSetCatalogDb() {
+ config.setCatalogDbName("foo");
+ assert config.getCatalogDbName().equals("foo");
+ }
+
+}
Property changes on: trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/BdbjeCacheStoreConfigTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:mergeinfo
+
Name: svn:eol-style
+ LF
Added: trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/BdbjeCacheStoreIntegrationTest.java
===================================================================
--- trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/BdbjeCacheStoreIntegrationTest.java (rev 0)
+++ trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/BdbjeCacheStoreIntegrationTest.java 2009-04-08 17:45:09 UTC (rev 103)
@@ -0,0 +1,109 @@
+package org.infinispan.loader.bdbje;
+
+import org.easymock.EasyMock;
+import org.infinispan.loader.BaseCacheStoreTest;
+import org.infinispan.loader.CacheLoaderException;
+import org.infinispan.loader.CacheStore;
+import org.infinispan.loader.modifications.Clear;
+import org.infinispan.loader.modifications.Modification;
+import org.infinispan.loader.modifications.Remove;
+import org.infinispan.loader.modifications.Store;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.container.entries.InternalEntryFactory;
+import org.testng.annotations.Test;
+
+import javax.transaction.Transaction;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Adrian Cole
+ * @version $Id$
+ * @since 4.0
+ */
+ at Test(groups = "unit", enabled = true, testName = "loader.bdbje.BdbjeCacheStoreIntegrationTest")
+public class BdbjeCacheStoreIntegrationTest extends BaseCacheStoreTest {
+
+ protected CacheStore createCacheStore() throws CacheLoaderException {
+ CacheStore cs = new BdbjeCacheStore();
+ String tmpDir = TestingUtil.TEST_FILES;
+ String tmpCLLoc = tmpDir + "/Horizon-BdbjeCacheStoreIntegrationTest";
+ TestingUtil.recursiveFileRemove(tmpCLLoc);
+
+ BdbjeCacheStoreConfig cfg = new BdbjeCacheStoreConfig();
+ cfg.setLocation(tmpCLLoc);
+ cfg.setPurgeSynchronously(true);
+ cs.init(cfg, getCache(), getMarshaller());
+ cs.start();
+ return cs;
+ }
+
+ /**
+ * this is the same as the superclass, except that it doesn't attempt read-committed
+ */
+ @Override
+ public void testTwoPhaseCommit() throws CacheLoaderException {
+ List<Modification> mods = new ArrayList<Modification>();
+ mods.add(new Store(InternalEntryFactory.create("k1", "v1")));
+ mods.add(new Store(InternalEntryFactory.create("k2", "v2")));
+ mods.add(new Remove("k1"));
+ Transaction tx = EasyMock.createNiceMock(Transaction.class);
+ cs.prepare(mods, tx, false);
+ cs.commit(tx);
+
+ assert cs.load("k2").getValue().equals("v2");
+ assert !cs.containsKey("k1");
+
+ cs.clear();
+
+ mods = new ArrayList<Modification>();
+ mods.add(new Store(InternalEntryFactory.create("k1", "v1")));
+ mods.add(new Store(InternalEntryFactory.create("k2", "v2")));
+ mods.add(new Clear());
+ mods.add(new Store(InternalEntryFactory.create("k3", "v3")));
+
+ cs.prepare(mods, tx, false);
+ cs.commit(tx);
+
+ assert !cs.containsKey("k1");
+ assert !cs.containsKey("k2");
+ assert cs.containsKey("k3");
+ }
+
+ /**
+ * this is the same as the superclass, except that it doesn't attempt read-committed
+ */
+ @Override
+ public void testRollback() throws CacheLoaderException {
+
+ cs.store(InternalEntryFactory.create("old", "old"));
+
+ List<Modification> mods = new ArrayList<Modification>();
+ mods.add(new Store(InternalEntryFactory.create("k1", "v1")));
+ mods.add(new Store(InternalEntryFactory.create("k2", "v2")));
+ mods.add(new Remove("k1"));
+ mods.add(new Remove("old"));
+ Transaction tx = EasyMock.createNiceMock(Transaction.class);
+ cs.prepare(mods, tx, false);
+ cs.rollback(tx);
+
+ assert !cs.containsKey("k1");
+ assert !cs.containsKey("k2");
+ assert cs.containsKey("old");
+
+ mods = new ArrayList<Modification>();
+ mods.add(new Store(InternalEntryFactory.create("k1", "v1")));
+ mods.add(new Store(InternalEntryFactory.create("k2", "v2")));
+ mods.add(new Clear());
+ mods.add(new Store(InternalEntryFactory.create("k3", "v3")));
+
+ cs.prepare(mods, tx, false);
+ cs.rollback(tx);
+
+ assert !cs.containsKey("k1");
+ assert !cs.containsKey("k2");
+ assert !cs.containsKey("k3");
+ assert cs.containsKey("old");
+ }
+
+}
Property changes on: trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/BdbjeCacheStoreIntegrationTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:mergeinfo
+
Name: svn:eol-style
+ LF
Added: trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/BdbjeCacheStoreTest.java
===================================================================
--- trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/BdbjeCacheStoreTest.java (rev 0)
+++ trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/BdbjeCacheStoreTest.java 2009-04-08 17:45:09 UTC (rev 103)
@@ -0,0 +1,359 @@
+package org.infinispan.loader.bdbje;
+
+import com.sleepycat.bind.serial.StoredClassCatalog;
+import com.sleepycat.collections.CurrentTransaction;
+import com.sleepycat.collections.StoredMap;
+import com.sleepycat.collections.TransactionWorker;
+import com.sleepycat.je.Cursor;
+import com.sleepycat.je.Database;
+import com.sleepycat.je.DatabaseException;
+import com.sleepycat.je.Environment;
+import com.sleepycat.util.RuntimeExceptionWrapper;
+import static org.easymock.classextension.EasyMock.*;
+import org.infinispan.Cache;
+import org.infinispan.container.entries.InternalEntryFactory;
+import org.infinispan.container.entries.InternalCacheEntry;
+import org.infinispan.loader.CacheLoaderException;
+import org.infinispan.loader.modifications.Store;
+import org.infinispan.util.ReflectionUtil;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import javax.transaction.Transaction;
+import java.io.File;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.lang.ref.WeakReference;
+import java.util.Collections;
+
+/**
+ * @author Adrian Cole
+ * @version $Id$
+ * @since 4.0
+ */
+ at Test(groups = "unit", enabled = true, testName = "loader.bdbje.BdbjeCacheStoreTest")
+public class BdbjeCacheStoreTest {
+ private BdbjeCacheStore cs;
+ private BdbjeCacheStoreConfig cfg;
+ private BdbjeResourceFactory factory;
+ private Cache cache;
+ private Environment env;
+ private Database cacheDb;
+ private Database catalogDb;
+ private StoredClassCatalog catalog;
+ private StoredMap cacheMap;
+ private PreparableTransactionRunner runner;
+ private CurrentTransaction currentTransaction;
+
+ private class MockBdbjeResourceFactory extends BdbjeResourceFactory {
+
+ @Override
+ public PreparableTransactionRunner createPreparableTransactionRunner(Environment env) {
+ return runner;
+ }
+
+ @Override
+ public CurrentTransaction createCurrentTransaction(Environment env) {
+ return currentTransaction;
+ }
+
+ @Override
+ public Environment createEnvironment(File envLocation) throws DatabaseException {
+ return env;
+ }
+
+ @Override
+ public StoredClassCatalog createStoredClassCatalog(Database catalogDb) throws DatabaseException {
+ return catalog;
+ }
+
+ @Override
+ public Database createDatabase(Environment env, String name) throws DatabaseException {
+ if (name.equals(cfg.getCacheDbName()))
+ return cacheDb;
+ else
+ return catalogDb;
+ }
+
+ @Override
+ public StoredMap createStoredMapViewOfDatabase(Database database, StoredClassCatalog classCatalog) throws DatabaseException {
+ return cacheMap;
+ }
+
+ public MockBdbjeResourceFactory(BdbjeCacheStoreConfig config) {
+ super(config);
+ }
+ }
+
+ @BeforeMethod
+ public void setUp() throws Exception {
+ cfg = new BdbjeCacheStoreConfig();
+ factory = new MockBdbjeResourceFactory(cfg);
+ cache = createMock(Cache.class);
+ cs = new BdbjeCacheStore();
+ env = createMock(Environment.class);
+ cacheDb = createMock(Database.class);
+ catalogDb = createMock(Database.class);
+ catalog = createMock(StoredClassCatalog.class);
+ cacheMap = createMock(StoredMap.class);
+ currentTransaction = createMock(CurrentTransaction.class);
+ WeakReference<Environment> envRef = new WeakReference<Environment>(env);
+ ReflectionUtil.setValue(currentTransaction,"envRef",envRef);
+ ThreadLocal localTrans = new ThreadLocal();
+ ReflectionUtil.setValue(currentTransaction,"localTrans",localTrans);
+ runner = createMock(PreparableTransactionRunner.class);
+ }
+
+ @AfterMethod
+ public void tearDown() throws CacheLoaderException {
+ runner = null;
+ currentTransaction = null;
+ cacheMap = null;
+ catalogDb = null;
+ cacheDb = null;
+ env = null;
+ factory = null;
+ cache = null;
+ cfg = null;
+ cs = null;
+ }
+
+ void start() throws DatabaseException, CacheLoaderException {
+ cs.init(cfg, factory, cache);
+ expect(cache.getName()).andReturn("cache");
+ }
+
+ @Test
+ public void testGetConfigurationClass() throws Exception {
+ replayAll();
+ assert cs.getConfigurationClass().equals(BdbjeCacheStoreConfig.class);
+ verifyAll();
+ }
+
+ void replayAll() throws Exception {
+ replay(runner);
+ replay(currentTransaction);
+ replay(cacheMap);
+ replay(catalog);
+ replay(catalogDb);
+ replay(cacheDb);
+ replay(env);
+ replay(cache);
+ }
+
+ void verifyAll() throws Exception {
+ verify(runner);
+ verify(currentTransaction);
+ verify(cacheMap);
+ verify(catalog);
+ verify(catalogDb);
+ verify(env);
+ verify(cache);
+ }
+
+ @Test
+ public void testInitNoMock() throws Exception {
+ replayAll();
+ cs.init(cfg, cache, null);
+ assert cfg.equals(ReflectionUtil.getValue(cs, "cfg"));
+ assert cache.equals(ReflectionUtil.getValue(cs, "cache"));
+ assert ReflectionUtil.getValue(cs, "factory") instanceof BdbjeResourceFactory;
+ verifyAll();
+ }
+
+ @Test
+ void testExceptionClosingCacheDatabaseDoesntPreventEnvironmentFromClosing() throws Exception {
+ start();
+ cacheDb.close();
+ expectLastCall().andThrow(new DatabaseException());
+ catalog.close();
+ env.close();
+ replayAll();
+ cs.start();
+ cs.stop();
+
+ verifyAll();
+ }
+
+ @Test
+ void testExceptionClosingCatalogDoesntPreventEnvironmentFromClosing() throws Exception {
+ start();
+ cacheDb.close();
+ catalog.close();
+ expectLastCall().andThrow(new DatabaseException());
+ env.close();
+ replayAll();
+ cs.start();
+ cs.stop();
+ verifyAll();
+ }
+
+ @Test(expectedExceptions = CacheLoaderException.class)
+ void testExceptionClosingEnvironment() throws Exception {
+ start();
+ cacheDb.close();
+ catalog.close();
+ env.close();
+ expectLastCall().andThrow(new DatabaseException());
+ replayAll();
+ cs.start();
+ cs.stop();
+ verifyAll();
+ }
+
+
+ @Test(expectedExceptions = CacheLoaderException.class)
+ void testThrowsCorrectExceptionOnStartForDatabaseException() throws Exception {
+ factory = new MockBdbjeResourceFactory(cfg) {
+ @Override
+ public StoredClassCatalog createStoredClassCatalog(Database catalogDb) throws DatabaseException {
+ throw new DatabaseException();
+ }
+ };
+ start();
+ replayAll();
+ cs.start();
+
+ }
+
+ @Test(expectedExceptions = CacheLoaderException.class)
+ void testEnvironmentDirectoryExistsButNotAFile() throws Exception {
+ File file = createMock(File.class);
+ expect(file.exists()).andReturn(true);
+ expect(file.isDirectory()).andReturn(false);
+ replay(file);
+ cs.verifyOrCreateEnvironmentDirectory(file);
+ }
+
+ @Test(expectedExceptions = CacheLoaderException.class)
+ void testCantCreateEnvironmentDirectory() throws Exception {
+ File file = createMock(File.class);
+ expect(file.exists()).andReturn(false);
+ expect(file.mkdirs()).andReturn(false);
+ replay(file);
+ cs.verifyOrCreateEnvironmentDirectory(file);
+ }
+
+ @Test
+ void testCanCreateEnvironmentDirectory() throws Exception {
+ File file = createMock(File.class);
+ expect(file.exists()).andReturn(false);
+ expect(file.mkdirs()).andReturn(true);
+ expect(file.isDirectory()).andReturn(true);
+ replay(file);
+ assert file.equals(cs.verifyOrCreateEnvironmentDirectory(file));
+ }
+
+ @Test
+ public void testNoExceptionOnRollback() throws Exception {
+ start();
+ Transaction tx = createMock(Transaction.class);
+ replayAll();
+ cs.start();
+ cs.rollback(tx);
+ verifyAll();
+ }
+
+ @Test
+ protected void testApplyModificationsThrowsOriginalDatabaseException() throws Exception {
+ start();
+ DatabaseException ex = new DatabaseException();
+ runner.run(isA(TransactionWorker.class));
+ expectLastCall().andThrow(new RuntimeExceptionWrapper(ex));
+ replayAll();
+ cs.start();
+ try {
+ cs.applyModifications(Collections.singletonList(new Store(InternalEntryFactory.create("k", "v"))));
+ assert false : "should have gotten an exception";
+ } catch (CacheLoaderException e) {
+ assert ex.equals(e.getCause());
+ verifyAll();
+ return;
+ }
+ assert false : "should have returned";
+
+ }
+
+ @Test
+ protected void testCommitThrowsOriginalDatabaseException() throws Exception {
+ start();
+ DatabaseException ex = new DatabaseException();
+ com.sleepycat.je.Transaction txn = createMock(com.sleepycat.je.Transaction.class);
+ expect(currentTransaction.beginTransaction(null)).andReturn(txn);
+ runner.prepare(isA(TransactionWorker.class));
+ txn.commit();
+ expectLastCall().andThrow(new RuntimeExceptionWrapper(ex));
+ replayAll();
+ replay(txn);
+ cs.start();
+ try {
+ txn = currentTransaction.beginTransaction(null);
+ Transaction t = createMock(Transaction.class);
+ cs.prepare(Collections.singletonList(new Store(InternalEntryFactory.create("k", "v"))), t,false);
+ cs.commit(t);
+ assert false : "should have gotten an exception";
+ } catch (CacheLoaderException e) {
+ assert ex.equals(e.getCause());
+ verifyAll();
+ return;
+ }
+ assert false : "should have returned";
+
+ }
+
+ @Test
+ protected void testPrepareThrowsOriginalDatabaseException() throws Exception {
+ start();
+ DatabaseException ex = new DatabaseException();
+ runner.prepare(isA(TransactionWorker.class));
+ expectLastCall().andThrow(new RuntimeExceptionWrapper(ex));
+ replayAll();
+ cs.start();
+ try {
+ cs.prepare(Collections.singletonList(new Store(InternalEntryFactory.create("k", "v"))), createMock(Transaction.class),false);
+ assert false : "should have gotten an exception";
+ } catch (CacheLoaderException e) {
+ assert ex.equals(e.getCause());
+ verifyAll();
+ return;
+ }
+ assert false : "should have returned";
+
+ }
+
+ @Test
+ void testClearOnAbortFromStream() throws Exception {
+ start();
+ InternalCacheEntry entry = InternalEntryFactory.create("key", "value");
+ expect(cacheMap.put(entry.getKey(), entry)).andReturn(null);
+ ObjectInput ois = createMock(ObjectInput.class);
+ expect(ois.readLong()).andReturn(new Long(1));
+ com.sleepycat.je.Transaction txn = createMock( com.sleepycat.je.Transaction.class);
+ expect(currentTransaction.beginTransaction(null)).andReturn(txn);
+ cacheMap.clear();
+ Cursor cursor = createMock(Cursor.class);
+ expect(cacheDb.openCursor(txn, null)).andReturn(cursor);
+ IOException ex = new IOException();
+ expect(ois.readObject()).andReturn(new byte[0]);
+ expectLastCall().andThrow(ex);
+ txn.abort();
+ cacheMap.clear();
+ replay(ois);
+ replay(txn);
+ replayAll();
+ cs.start();
+ try {
+ cs.store(entry);
+ cs.fromStream(ois);
+ assert false : "should have gotten an exception";
+ } catch (CacheLoaderException e) {
+ assert ex.equals(e.getCause());
+ verifyAll();
+ verify(ois);
+ verify(txn);
+ return;
+ }
+ assert false : "should have returned";
+ }
+}
Property changes on: trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/BdbjeCacheStoreTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:mergeinfo
+
Name: svn:eol-style
+ LF
Added: trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/BdbjeLearningTest.java
===================================================================
--- trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/BdbjeLearningTest.java (rev 0)
+++ trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/BdbjeLearningTest.java 2009-04-08 17:45:09 UTC (rev 103)
@@ -0,0 +1,693 @@
+package org.infinispan.loader.bdbje;
+
+import com.sleepycat.bind.EntryBinding;
+import com.sleepycat.bind.serial.SerialBinding;
+import com.sleepycat.bind.serial.StoredClassCatalog;
+import com.sleepycat.collections.CurrentTransaction;
+import com.sleepycat.collections.StoredMap;
+import com.sleepycat.collections.TransactionRunner;
+import com.sleepycat.collections.TransactionWorker;
+import com.sleepycat.je.Cursor;
+import com.sleepycat.je.Database;
+import com.sleepycat.je.DatabaseConfig;
+import com.sleepycat.je.DatabaseEntry;
+import com.sleepycat.je.DatabaseException;
+import com.sleepycat.je.Environment;
+import com.sleepycat.je.EnvironmentConfig;
+import com.sleepycat.je.OperationStatus;
+import org.easymock.EasyMock;
+import org.infinispan.loader.CacheLoaderException;
+import org.infinispan.loader.modifications.Clear;
+import org.infinispan.loader.modifications.Modification;
+import org.infinispan.loader.modifications.Remove;
+import org.infinispan.loader.modifications.Store;
+import org.infinispan.logging.Log;
+import org.infinispan.logging.LogFactory;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.container.entries.InternalCacheEntry;
+import org.infinispan.container.entries.InternalEntryFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import javax.transaction.Transaction;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+
+/**
+ * Learning tests for SleepyCat JE. Behaviour here is used in BdbjeCacheLoader. When there are upgrades to bdbje, this
+ * test may warrant updating.
+ *
+ * @author Adrian Cole
+ * @version $Id$
+ * @since 4.0
+ */
+ at Test(groups = "unit", enabled = true, testName = "loader.bdbje.BdbjeLearningTest")
+public class BdbjeLearningTest {
+ String dbHome = TestingUtil.TEST_FILES + "/Horizon-BdbjeLearningTest";
+ Environment env;
+
+ private static final String CLASS_CATALOG = "java_class_catalog";
+ private StoredClassCatalog javaCatalog;
+
+ private static final String STORED_ENTRIES = "storedEntriesDb";
+ private Database storedEntriesDb;
+ private StoredMap<Object, InternalCacheEntry> cacheMap;
+
+
+ @BeforeMethod
+ public void setUp() throws Exception {
+ new File(dbHome).mkdirs();
+ System.out.println("Opening environment in: " + dbHome);
+
+ EnvironmentConfig envConfig = new EnvironmentConfig();
+ envConfig.setTransactional(true);
+ envConfig.setAllowCreate(true);
+
+ env = new Environment(new File(dbHome), envConfig);
+ DatabaseConfig dbConfig = new DatabaseConfig();
+ dbConfig.setTransactional(true);
+ dbConfig.setAllowCreate(true);
+
+ Database catalogDb = env.openDatabase(null, CLASS_CATALOG, dbConfig);
+
+ javaCatalog = new StoredClassCatalog(catalogDb);
+
+ EntryBinding storedEntryKeyBinding =
+ new SerialBinding(javaCatalog, Object.class);
+ EntryBinding storedEntryValueBinding =
+ new SerialBinding(javaCatalog, InternalCacheEntry.class);
+
+ storedEntriesDb = env.openDatabase(null, STORED_ENTRIES, dbConfig);
+
+ cacheMap =
+ new StoredMap<Object, InternalCacheEntry>(storedEntriesDb,
+ storedEntryKeyBinding, storedEntryValueBinding, true);
+
+
+ }
+
+ public void testTransactionWorker() throws Exception {
+ TransactionRunner runner = new TransactionRunner(env);
+ runner.run(new PopulateDatabase());
+ runner.run(new PrintDatabase());
+
+ }
+
+
+ private class PopulateDatabase implements TransactionWorker {
+ public void doWork()
+ throws Exception {
+ }
+ }
+
+ private class PrintDatabase implements TransactionWorker {
+ public void doWork()
+ throws Exception {
+ }
+ }
+
+
+ @AfterMethod
+ public void tearDown() throws Exception {
+ storedEntriesDb.close();
+ javaCatalog.close();
+ env.close();
+
+ TestingUtil.recursiveFileRemove(dbHome);
+ }
+
+
+ private void store(InternalCacheEntry se) {
+ cacheMap.put(se.getKey(), se);
+ }
+
+
+ private InternalCacheEntry load(Object key) {
+ InternalCacheEntry s = cacheMap.get(key);
+ if (s == null)
+ return null;
+ if (!s.isExpired())
+ return s;
+ else
+ cacheMap.remove(key);
+ return null;
+ }
+
+ private Set loadAll() {
+ return new HashSet(cacheMap.values());
+ }
+
+ private void purgeExpired() {
+ Iterator<Map.Entry<Object, InternalCacheEntry>> i = cacheMap.entrySet().iterator();
+ while (i.hasNext()) {
+ if (i.next().getValue().isExpired())
+ i.remove();
+ }
+ }
+
+ private static final Log log = LogFactory.getLog(BdbjeLearningTest.class);
+
+ private void toStream(OutputStream outputStream) throws CacheLoaderException {
+ ObjectOutputStream oos = null;
+ Cursor cursor = null;
+
+ try {
+ oos = (outputStream instanceof ObjectOutputStream) ? (ObjectOutputStream) outputStream :
+ new ObjectOutputStream(outputStream);
+ long recordCount = storedEntriesDb.count();
+ log.trace("writing {0} records to stream", recordCount);
+ oos.writeLong(recordCount);
+
+ cursor = storedEntriesDb.openCursor(null, null);
+ DatabaseEntry key = new DatabaseEntry();
+ DatabaseEntry data = new DatabaseEntry();
+ while (cursor.getNext(key, data, null) ==
+ OperationStatus.SUCCESS) {
+ oos.writeObject(key.getData());
+ oos.writeObject(data.getData());
+ }
+ } catch (IOException e) {
+ throw new CacheLoaderException("Error writing to object stream", e);
+ } catch (DatabaseException e) {
+ throw new CacheLoaderException("Error accessing database", e);
+ }
+ finally {
+ if (cursor != null) try {
+ cursor.close();
+ } catch (DatabaseException e) {
+ throw new CacheLoaderException("Error closing cursor", e);
+ }
+ }
+
+ }
+
+ private void fromStream(InputStream inputStream) throws CacheLoaderException {
+ ObjectInputStream ois = null;
+ try {
+ ois = (inputStream instanceof ObjectInputStream) ? (ObjectInputStream) inputStream :
+ new ObjectInputStream(inputStream);
+ long recordCount = ois.readLong();
+ log.info("reading {0} records from stream", recordCount);
+ log.info("clearing all records");
+ cacheMap.clear();
+ Cursor cursor = null;
+ com.sleepycat.je.Transaction txn = env.beginTransaction(null, null);
+ try {
+ cursor = storedEntriesDb.openCursor(txn, null);
+ for (int i = 0; i < recordCount; i++) {
+ byte[] keyBytes = (byte[]) ois.readObject();
+ byte[] dataBytes = (byte[]) ois.readObject();
+
+ DatabaseEntry key = new DatabaseEntry(keyBytes);
+ DatabaseEntry data = new DatabaseEntry(dataBytes);
+ cursor.put(key, data);
+ }
+ cursor.close();
+ cursor = null;
+ txn.commit();
+ } finally {
+ if (cursor != null) cursor.close();
+ }
+
+ }
+ catch (Exception e) {
+ CacheLoaderException cle = (e instanceof CacheLoaderException) ? (CacheLoaderException) e :
+ new CacheLoaderException("Problems reading from stream", e);
+ throw cle;
+ }
+ }
+
+ class StoreTransactionWorker implements TransactionWorker {
+ StoreTransactionWorker(InternalCacheEntry entry) {
+ this.entry = entry;
+ }
+
+ private InternalCacheEntry entry;
+
+ public void doWork() throws Exception {
+ store(entry);
+ }
+ }
+
+ class ClearTransactionWorker implements TransactionWorker {
+
+ public void doWork() throws Exception {
+ cacheMap.clear();
+ }
+ }
+
+ class RemoveTransactionWorker implements TransactionWorker {
+ RemoveTransactionWorker(Object key) {
+ this.key = key;
+ }
+
+ Object key;
+
+ public void doWork() throws Exception {
+ cacheMap.remove(key);
+ }
+ }
+
+ class PurgeExpiredTransactionWorker implements TransactionWorker {
+ public void doWork() throws Exception {
+ purgeExpired();
+ }
+ }
+
+ class ModificationsTransactionWorker implements TransactionWorker {
+ private List<? extends Modification> mods;
+
+ ModificationsTransactionWorker(List<? extends Modification> mods) {
+ this.mods = mods;
+ }
+
+ public void doWork() throws Exception {
+ for (Modification modification : mods)
+ switch (modification.getType()) {
+ case STORE:
+ Store s = (Store) modification;
+ store(s.getStoredEntry());
+ break;
+ case CLEAR:
+ cacheMap.clear();
+ break;
+ case REMOVE:
+ Remove r = (Remove) modification;
+ cacheMap.remove(r.getKey());
+ break;
+ case PURGE_EXPIRED:
+ purgeExpired();
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown modification type " + modification.getType());
+ }
+ }
+ }
+
+
+ private void prepare(List<Modification> mods, Transaction tx, boolean isOnePhase) throws CacheLoaderException {
+ if (isOnePhase) {
+ TransactionRunner runner = new TransactionRunner(env);
+ try {
+ runner.run(new ModificationsTransactionWorker(mods));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ } else {
+ PreparableTransactionRunner runner = new PreparableTransactionRunner(env);
+ com.sleepycat.je.Transaction txn = null;
+ try {
+ runner.prepare(new ModificationsTransactionWorker(mods));
+ txn = CurrentTransaction.getInstance(env).getTransaction();
+ txnMap.put(tx, txn);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+
+ Map<Transaction, com.sleepycat.je.Transaction> txnMap = new HashMap<Transaction, com.sleepycat.je.Transaction>();
+
+ private void commit(Transaction tx) {
+ com.sleepycat.je.Transaction txn = txnMap.remove(tx);
+ CurrentTransaction currentTransaction = CurrentTransaction.getInstance(env);
+ if (txn != null) {
+ if (currentTransaction.getTransaction() == txn) {
+ try {
+ currentTransaction.commitTransaction();
+ } catch (DatabaseException e) {
+ e.printStackTrace();
+ }
+ } else {
+ log.error("Transactions must be committed on the same thread");
+ }
+ }
+ }
+
+ private void rollback(Transaction tx) {
+ com.sleepycat.je.Transaction txn = txnMap.remove(tx);
+ CurrentTransaction currentTransaction = CurrentTransaction.getInstance(env);
+ if (txn != null) {
+ if (currentTransaction.getTransaction() == txn) {
+ try {
+ currentTransaction.abortTransaction();
+ } catch (DatabaseException e) {
+ e.printStackTrace();
+ }
+ } else {
+ log.error("Transactions must be committed on the same thread");
+ }
+ }
+ }
+
+ public void testLoadAndStore() throws InterruptedException, CacheLoaderException {
+ assert !cacheMap.containsKey("k");
+ InternalCacheEntry se = InternalEntryFactory.create("k", "v");
+ store(se);
+
+ assert load("k").getValue().equals("v");
+ assert load("k").getLifespan() == -1;
+ assert !load("k").isExpired();
+ assert cacheMap.containsKey("k");
+
+ long lifespan = 120000;
+ se = InternalEntryFactory.create("k", "v", lifespan);
+ store(se);
+
+ assert load("k").getValue().equals("v");
+ assert load("k").getLifespan() == lifespan;
+ assert !load("k").isExpired();
+ assert cacheMap.containsKey("k");
+
+ lifespan = 1;
+ se = InternalEntryFactory.create("k", "v", lifespan);
+ store(se);
+ Thread.sleep(100);
+ assert se.isExpired();
+ assert load("k") == null;
+ assert !cacheMap.containsKey("k");
+ }
+
+
+ public void testOnePhaseCommit() throws CacheLoaderException {
+ List<Modification> mods = new ArrayList<Modification>();
+ mods.add(new Store(InternalEntryFactory.create("k1", "v1")));
+ mods.add(new Store(InternalEntryFactory.create("k2", "v2")));
+ mods.add(new Remove("k1"));
+ Transaction tx = EasyMock.createNiceMock(Transaction.class);
+ prepare(mods, tx, true);
+
+ Set s = loadAll();
+
+ assert load("k2").getValue().equals("v2");
+ assert !cacheMap.containsKey("k1");
+
+ cacheMap.clear();
+
+ mods = new ArrayList<Modification>();
+ mods.add(new Store(InternalEntryFactory.create("k1", "v1")));
+ mods.add(new Store(InternalEntryFactory.create("k2", "v2")));
+ mods.add(new Clear());
+ mods.add(new Store(InternalEntryFactory.create("k3", "v3")));
+
+ prepare(mods, tx, true);
+ assert !cacheMap.containsKey("k1");
+ assert !cacheMap.containsKey("k2");
+ assert cacheMap.containsKey("k3");
+ }
+
+
+ public void testTwoPhaseCommit() throws Throwable {
+ final List<Throwable> throwables = new ArrayList<Throwable>();
+ List<Modification> mods = new ArrayList<Modification>();
+ mods.add(new Store(InternalEntryFactory.create("k1", "v1")));
+ mods.add(new Store(InternalEntryFactory.create("k2", "v2")));
+ mods.add(new Remove("k1"));
+ Transaction tx = EasyMock.createNiceMock(Transaction.class);
+ prepare(mods, tx, false);
+
+
+ Thread gets1 = new Thread(
+ new Runnable() {
+ public void run() {
+ try {
+ assert load("k2").getValue().equals("v2");
+ assert !cacheMap.containsKey("k1");
+ } catch (Throwable e) {
+ throwables.add(e);
+ }
+ }
+ }
+ );
+
+ gets1.start();
+ commit(tx);
+
+ gets1.join();
+
+ if (!throwables.isEmpty()) throw throwables.get(0);
+
+
+ cacheMap.clear();
+
+ mods = new ArrayList<Modification>();
+ mods.add(new Store(InternalEntryFactory.create("k1", "v1")));
+ mods.add(new Store(InternalEntryFactory.create("k2", "v2")));
+ mods.add(new Clear());
+ mods.add(new Store(InternalEntryFactory.create("k3", "v3")));
+
+ prepare(mods, tx, false);
+
+ Thread gets2 = new Thread(
+ new Runnable() {
+ public void run() {
+ try {
+ assert !cacheMap.containsKey("k1");
+ assert !cacheMap.containsKey("k2");
+ assert cacheMap.containsKey("k3");
+
+ } catch (Throwable e) {
+ throwables.add(e);
+ }
+ }
+ }
+ );
+
+ gets2.start();
+
+
+ commit(tx);
+ gets2.join();
+
+ if (!throwables.isEmpty()) throw throwables.get(0);
+ assert !cacheMap.containsKey("k1");
+ assert !cacheMap.containsKey("k2");
+ assert cacheMap.containsKey("k3");
+ }
+
+
+ public void testRollback() throws Throwable {
+
+ store(InternalEntryFactory.create("old", "old"));
+
+
+ List<Modification> mods = new ArrayList<Modification>();
+ mods.add(new Store(InternalEntryFactory.create("k1", "v1")));
+ mods.add(new Store(InternalEntryFactory.create("k2", "v2")));
+ mods.add(new Remove("k1"));
+ mods.add(new Remove("old"));
+ Transaction tx = EasyMock.createNiceMock(Transaction.class);
+ prepare(mods, tx, false);
+
+ rollback(tx);
+
+ assert !cacheMap.containsKey("k1");
+ assert !cacheMap.containsKey("k2");
+ assert cacheMap.containsKey("old");
+
+ mods = new ArrayList<Modification>();
+ mods.add(new Store(InternalEntryFactory.create("k1", "v1")));
+ mods.add(new Store(InternalEntryFactory.create("k2", "v2")));
+ mods.add(new Clear());
+ mods.add(new Store(InternalEntryFactory.create("k3", "v3")));
+
+ prepare(mods, tx, false);
+
+ rollback(tx);
+
+ assert !cacheMap.containsKey("k1");
+ assert !cacheMap.containsKey("k2");
+ assert !cacheMap.containsKey("k3");
+ assert cacheMap.containsKey("old");
+ }
+
+
+ public void testCommitAndRollbackWithoutPrepare() throws CacheLoaderException {
+ store(InternalEntryFactory.create("old", "old"));
+ Transaction tx = EasyMock.createNiceMock(Transaction.class);
+ commit(tx);
+ store(InternalEntryFactory.create("old", "old"));
+ rollback(tx);
+
+ assert cacheMap.containsKey("old");
+ }
+
+ public void testPreload() throws CacheLoaderException {
+ store(InternalEntryFactory.create("k1", "v1"));
+ store(InternalEntryFactory.create("k2", "v2"));
+ store(InternalEntryFactory.create("k3", "v3"));
+
+ Set<InternalCacheEntry> set = loadAll();
+
+ assert set.size() == 3;
+ Set expected = new HashSet();
+ expected.add("k1");
+ expected.add("k2");
+ expected.add("k3");
+ for (InternalCacheEntry se : set) assert expected.remove(se.getKey());
+ assert expected.isEmpty();
+ }
+
+ public void testPurgeExpired() throws Exception {
+ long now = System.currentTimeMillis();
+ long lifespan = 1000;
+ store(InternalEntryFactory.create("k1", "v1", lifespan));
+ store(InternalEntryFactory.create("k2", "v2", lifespan));
+ store(InternalEntryFactory.create("k3", "v3", lifespan));
+
+ assert cacheMap.containsKey("k1");
+ assert cacheMap.containsKey("k2");
+ assert cacheMap.containsKey("k3");
+ Thread.sleep(lifespan + 100);
+ purgeExpired();
+ assert !cacheMap.containsKey("k1");
+ assert !cacheMap.containsKey("k2");
+ assert !cacheMap.containsKey("k3");
+ }
+
+
+ public void testStreamingAPI() throws IOException, ClassNotFoundException, CacheLoaderException {
+ store(InternalEntryFactory.create("k1", "v1"));
+ store(InternalEntryFactory.create("k2", "v2"));
+ store(InternalEntryFactory.create("k3", "v3"));
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ toStream(out);
+ out.close();
+ cacheMap.clear();
+ fromStream(new ByteArrayInputStream(out.toByteArray()));
+
+ Set<InternalCacheEntry> set = loadAll();
+
+ assert set.size() == 3;
+ Set expected = new HashSet();
+ expected.add("k1");
+ expected.add("k2");
+ expected.add("k3");
+ for (InternalCacheEntry se : set) assert expected.remove(se.getKey());
+ assert expected.isEmpty();
+ }
+
+
+ public void testStreamingAPIReusingStreams() throws IOException, ClassNotFoundException, CacheLoaderException {
+ store(InternalEntryFactory.create("k1", "v1"));
+ store(InternalEntryFactory.create("k2", "v2"));
+ store(InternalEntryFactory.create("k3", "v3"));
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ byte[] dummyStartBytes = {1, 2, 3, 4, 5, 6, 7, 8};
+ byte[] dummyEndBytes = {8, 7, 6, 5, 4, 3, 2, 1};
+ out.write(dummyStartBytes);
+ toStream(out);
+ out.write(dummyEndBytes);
+ out.close();
+ cacheMap.clear();
+
+ // first pop the start bytes
+ byte[] dummy = new byte[8];
+ ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+ int bytesRead = in.read(dummy, 0, 8);
+ assert bytesRead == 8;
+ for (int i = 1; i < 9; i++) assert dummy[i - 1] == i : "Start byte stream corrupted!";
+ fromStream(in);
+ bytesRead = in.read(dummy, 0, 8);
+ assert bytesRead == 8;
+ for (int i = 8; i > 0; i--) assert dummy[8 - i] == i : "Start byte stream corrupted!";
+
+ Set<InternalCacheEntry> set = loadAll();
+
+ assert set.size() == 3;
+ Set expected = new HashSet();
+ expected.add("k1");
+ expected.add("k2");
+ expected.add("k3");
+ for (InternalCacheEntry se : set) assert expected.remove(se.getKey());
+ assert expected.isEmpty();
+ }
+
+ public void testConcurrency() throws Throwable {
+ int numThreads = 3;
+ final int loops = 500;
+ final String[] keys = new String[10];
+ final String[] values = new String[10];
+ for (int i = 0; i < 10; i++) keys[i] = "k" + i;
+ for (int i = 0; i < 10; i++) values[i] = "v" + i;
+
+
+ final Random r = new Random();
+ final List<Throwable> throwables = new LinkedList<Throwable>();
+
+ final Runnable store = new Runnable() {
+ public void run() {
+ try {
+ int randomInt = r.nextInt(10);
+ store(InternalEntryFactory.create(keys[randomInt], values[randomInt]));
+ } catch (Throwable e) {
+ throwables.add(e);
+ }
+ }
+ };
+
+ final Runnable remove = new Runnable() {
+ public void run() {
+ try {
+ cacheMap.remove(keys[r.nextInt(10)]);
+ } catch (Throwable e) {
+ throwables.add(e);
+ }
+ }
+ };
+
+ final Runnable get = new Runnable() {
+ public void run() {
+ try {
+ int randomInt = r.nextInt(10);
+ InternalCacheEntry se = load(keys[randomInt]);
+ assert se == null || se.getValue().equals(values[randomInt]);
+ loadAll();
+ } catch (Throwable e) {
+ throwables.add(e);
+ }
+ }
+ };
+
+ Thread[] threads = new Thread[numThreads];
+
+ for (int i = 0; i < numThreads; i++) {
+ threads[i] = new Thread(getClass().getSimpleName() + "-" + i) {
+ public void run() {
+ for (int i = 0; i < loops; i++) {
+ store.run();
+ remove.run();
+ get.run();
+ }
+ }
+ };
+ }
+
+ for (Thread t : threads) t.start();
+ for (Thread t : threads) t.join();
+
+ if (!throwables.isEmpty()) throw throwables.get(0);
+ }
+
+
+}
+
Property changes on: trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/BdbjeLearningTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:mergeinfo
+
Name: svn:eol-style
+ LF
Added: trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/BdbjeResourceFactoryTest.java
===================================================================
--- trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/BdbjeResourceFactoryTest.java (rev 0)
+++ trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/BdbjeResourceFactoryTest.java 2009-04-08 17:45:09 UTC (rev 103)
@@ -0,0 +1,48 @@
+package org.infinispan.loader.bdbje;
+
+import com.sleepycat.bind.serial.StoredClassCatalog;
+import com.sleepycat.je.Database;
+import com.sleepycat.je.DatabaseException;
+import com.sleepycat.je.Environment;
+import static org.easymock.classextension.EasyMock.createMock;
+import org.infinispan.loader.CacheLoaderException;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/**
+ * @author Adrian Cole
+ * @version $Id$
+ * @since 4.0
+ */
+ at Test(groups = "unit", enabled = true, testName = "loader.bdbje.BdbjeResourceFactoryTest")
+public class BdbjeResourceFactoryTest {
+ private BdbjeCacheStoreConfig cfg;
+ private Environment env;
+ private BdbjeResourceFactory factory;
+ private Database cacheDb;
+ private StoredClassCatalog catalog;
+
+ @BeforeMethod
+ public void setUp() throws Exception {
+ cfg = new BdbjeCacheStoreConfig();
+ factory = new BdbjeResourceFactory(cfg);
+ env = createMock(Environment.class);
+ cacheDb = createMock(Database.class);
+ catalog = createMock(StoredClassCatalog.class);
+ }
+
+ @AfterMethod
+ public void tearDown() throws CacheLoaderException {
+ env = null;
+ factory = null;
+ cfg = null;
+ cacheDb = null;
+ catalog = null;
+ }
+
+ @Test(expectedExceptions = DatabaseException.class)
+ public void testCreateStoredMapViewOfDatabaseThrowsException() throws DatabaseException {
+ factory.createStoredMapViewOfDatabase(cacheDb, catalog);
+ }
+}
Property changes on: trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/BdbjeResourceFactoryTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:mergeinfo
+
Name: svn:eol-style
+ LF
Added: trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/ModificationsTransactionWorkerTest.java
===================================================================
--- trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/ModificationsTransactionWorkerTest.java (rev 0)
+++ trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/ModificationsTransactionWorkerTest.java 2009-04-08 17:45:09 UTC (rev 103)
@@ -0,0 +1,107 @@
+package org.infinispan.loader.bdbje;
+
+import static org.easymock.classextension.EasyMock.*;
+import org.infinispan.loader.CacheStore;
+import org.infinispan.loader.modifications.Clear;
+import org.infinispan.loader.modifications.Modification;
+import org.infinispan.loader.modifications.PurgeExpired;
+import org.infinispan.loader.modifications.Remove;
+import org.infinispan.loader.modifications.Store;
+import org.infinispan.container.entries.InternalEntryFactory;
+import org.infinispan.container.entries.InternalCacheEntry;
+import org.testng.annotations.Test;
+
+import java.util.Collections;
+
+/**
+ * Unit tests that cover {@link ModificationsTransactionWorker }
+ *
+ * @author Adrian Cole
+ * @version $Id$
+ * @since 4.0
+ */
+ at Test(groups = "unit", enabled = true, testName = "loader.bdbje.ModificationsTransactionWorkerTest")
+public class ModificationsTransactionWorkerTest {
+
+ @Test
+ public void testDoWorkOnStore() throws Exception {
+ CacheStore cs = createMock(CacheStore.class);
+ Store store = createMock(Store.class);
+ InternalCacheEntry entry = InternalEntryFactory.create("1", "2");
+ expect(store.getType()).andReturn(Modification.Type.STORE);
+ expect(store.getStoredEntry()).andReturn(entry);
+ cs.store(entry);
+ replay(cs);
+ replay(store);
+
+ ModificationsTransactionWorker worker =
+ new ModificationsTransactionWorker(cs,
+ Collections.singletonList(store));
+ worker.doWork();
+ verify(cs);
+ verify(store);
+
+ }
+
+ @Test
+ public void testDoWorkOnRemove() throws Exception {
+ CacheStore cs = createMock(CacheStore.class);
+ Remove store = createMock(Remove.class);
+ expect(store.getType()).andReturn(Modification.Type.REMOVE);
+ expect(store.getKey()).andReturn("1");
+ expect(cs.remove("1")).andReturn(true);
+ replay(cs);
+ replay(store);
+
+ ModificationsTransactionWorker worker =
+ new ModificationsTransactionWorker(cs,
+ Collections.singletonList(store));
+ worker.doWork();
+ verify(cs);
+ verify(store);
+
+ }
+
+ @Test
+ public void testDoWorkOnClear() throws Exception {
+ CacheStore cs = createMock(CacheStore.class);
+ Clear clear = createMock(Clear.class);
+ expect(clear.getType()).andReturn(Modification.Type.CLEAR);
+ cs.clear();
+ replay(cs);
+ replay(clear);
+
+ ModificationsTransactionWorker worker =
+ new ModificationsTransactionWorker(cs,
+ Collections.singletonList(clear));
+ worker.doWork();
+ verify(cs);
+ verify(clear);
+ }
+
+ @Test
+ public void testDoWorkOnPurgeExpired() throws Exception {
+ CacheStore cs = createMock(CacheStore.class);
+ PurgeExpired purge = createMock(PurgeExpired.class);
+ expect(purge.getType()).andReturn(Modification.Type.PURGE_EXPIRED);
+ cs.purgeExpired();
+ replay(cs);
+ replay(purge);
+
+ ModificationsTransactionWorker worker =
+ new ModificationsTransactionWorker(cs,
+ Collections.singletonList(purge));
+ worker.doWork();
+ verify(cs);
+ verify(purge);
+ }
+
+
+// case REMOVE:
+// Remove r = (Remove) modification;
+// cs.remove(r.getKey());
+// break;
+// default:
+// throw new IllegalArgumentException("Unknown modification type " + modification.getType());
+
+}
Property changes on: trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/ModificationsTransactionWorkerTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:mergeinfo
+
Name: svn:eol-style
+ LF
Added: trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/PreparableTransactionRunnerTest.java
===================================================================
--- trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/PreparableTransactionRunnerTest.java (rev 0)
+++ trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/PreparableTransactionRunnerTest.java 2009-04-08 17:45:09 UTC (rev 103)
@@ -0,0 +1,239 @@
+package org.infinispan.loader.bdbje;
+
+import com.sleepycat.collections.CurrentTransaction;
+import com.sleepycat.collections.TransactionWorker;
+import com.sleepycat.je.DeadlockException;
+import com.sleepycat.je.Environment;
+import com.sleepycat.je.EnvironmentConfig;
+import com.sleepycat.je.Transaction;
+import com.sleepycat.je.TransactionConfig;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.classextension.EasyMock.*;
+import org.infinispan.loader.CacheLoaderException;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/**
+ * Unit tests that cover {@link PreparableTransactionRunner }
+ *
+ * @author Adrian Cole
+ * @version $Id$
+ * @since 4.0
+ */
+ at Test(groups = "unit", enabled = true, testName = "loader.bdbje.PreparableTransactionRunnerTest")
+public class PreparableTransactionRunnerTest {
+ PreparableTransactionRunner runner;
+ Environment env;
+ EnvironmentConfig config;
+ TransactionWorker worker;
+ Transaction transaction;
+
+ @BeforeMethod
+ public void setUp() throws Exception {
+ config = createMock(EnvironmentConfig.class);
+ expect(config.getTransactional()).andReturn(true);
+ expect(config.getLocking()).andReturn(true);
+ transaction = createMock(Transaction.class);
+ env = createMock(Environment.class);
+ expect(env.getConfig()).andReturn(config);
+ expect(env.beginTransaction(null, null)).andReturn(transaction);
+ worker = createMock(TransactionWorker.class);
+ }
+
+ @AfterMethod
+ public void tearDown() throws CacheLoaderException {
+ runner = null;
+ env = null;
+ config = null;
+ }
+
+
+ @Test
+ public void testMoreDeadlocks() throws Exception {
+ worker.doWork();
+ expectLastCall().andThrow(new DeadlockException());
+ transaction.abort();
+ expect(env.beginTransaction(null, null)).andReturn(transaction);
+ worker.doWork();
+ expectLastCall().andThrow(new DeadlockException());
+ transaction.abort();
+ expect(env.beginTransaction(null, null)).andReturn(transaction);
+ worker.doWork();
+ expectLastCall().andThrow(new DeadlockException());
+ transaction.abort();
+ replayAll();
+ runner = new PreparableTransactionRunner(env, 2, null);
+ try {
+ runner.prepare(worker);
+ assert false : "should have gotten a deadlock exception";
+ } catch (DeadlockException e) {
+
+ }
+ verifyAll();
+ }
+
+ @Test
+ public void testPrepare() throws Exception {
+
+ worker.doWork();
+ replayAll();
+ runner = new PreparableTransactionRunner(env);
+ runner.prepare(worker);
+ verifyAll();
+ }
+
+ @Test
+ public void testRun() throws Exception {
+ transaction.commit();
+ worker.doWork();
+ replayAll();
+ runner = new PreparableTransactionRunner(env);
+ runner.run(worker);
+ verifyAll();
+ }
+
+
+ @Test
+ public void testOneArgConstructorSetsCurrentTxn() throws Exception {
+ replayAll();
+ runner = new PreparableTransactionRunner(env);
+ assert CurrentTransaction.getInstance(env) == runner.currentTxn;
+ }
+
+ @Test
+ public void testSetMaxRetries() throws Exception {
+ replayAll();
+ runner = new PreparableTransactionRunner(env);
+ runner.setMaxRetries(1);
+ assert runner.getMaxRetries() == 1;
+ }
+
+ @Test
+ public void testSetAllowNestedTransactions() throws Exception {
+ replayAll();
+ runner = new PreparableTransactionRunner(env);
+ runner.setAllowNestedTransactions(false);
+ assert !runner.getAllowNestedTransactions();
+ try {
+ runner.setAllowNestedTransactions(true);
+ assert false : "should have gotten Exception";
+ } catch (UnsupportedOperationException e) {}
+ }
+
+ @Test
+ public void testGetTransactionConfig() throws Exception {
+ replayAll();
+ TransactionConfig config = new TransactionConfig();
+ runner = new PreparableTransactionRunner(env);
+ runner.setTransactionConfig(config);
+ assert runner.getTransactionConfig().equals(config);
+ }
+
+
+ @Test
+ public void testExceptionThrownInPrepare() throws Exception {
+
+ worker.doWork();
+ expectLastCall().andThrow(new RuntimeException());
+ transaction.abort();
+ replayAll();
+ runner = new PreparableTransactionRunner(env);
+
+ try {
+ runner.prepare(worker);
+ assert false : "should have gotten an exception";
+ } catch (RuntimeException e) {
+
+ }
+ verifyAll();
+ }
+
+ @Test
+ public void testErrorThrownInPrepare() throws Exception {
+
+ worker.doWork();
+ expectLastCall().andThrow(new Error());
+ transaction.abort();
+ replayAll();
+ runner = new PreparableTransactionRunner(env);
+
+ try {
+ runner.prepare(worker);
+ assert false : "should have gotten an exception";
+ } catch (Error e) {
+
+ }
+ verifyAll();
+ }
+
+
+ @Test
+ public void testExceptionThrownInRun() throws Exception {
+
+ worker.doWork();
+ expectLastCall().andThrow(new RuntimeException());
+ transaction.abort();
+ replayAll();
+ runner = new PreparableTransactionRunner(env);
+
+ try {
+ runner.prepare(worker);
+ assert false : "should have gotten an exception";
+ } catch (RuntimeException e) {
+
+ }
+ verifyAll();
+ }
+
+ @Test
+ public void testErrorThrownInRun() throws Exception {
+
+ worker.doWork();
+ expectLastCall().andThrow(new Error());
+ transaction.abort();
+ replayAll();
+ runner = new PreparableTransactionRunner(env);
+
+ try {
+ runner.run(worker);
+ assert false : "should have gotten an exception";
+ } catch (Error e) {
+
+ }
+ verifyAll();
+ }
+
+
+ public void testRethrowIfNotDeadLockDoesntThrowWhenGivenDeadlockException() throws Exception {
+ replayAll();
+ runner = new PreparableTransactionRunner(env);
+ runner.rethrowIfNotDeadLock(createNiceMock(DeadlockException.class));
+ }
+
+ public void testThrowableDuringAbort() throws Exception {
+ transaction.abort();
+ expectLastCall().andThrow(new RuntimeException());
+ replayAll();
+ runner = new PreparableTransactionRunner(env);
+ CurrentTransaction.getInstance(env).beginTransaction(null);
+ int max = runner.abortOverflowingCurrentTriesOnError(transaction, 2);
+ assert max == Integer.MAX_VALUE : "should have overflowed max tries, but got " + max;
+ verifyAll();
+ }
+
+ private void replayAll() {
+ replay(config);
+ replay(env);
+ replay(transaction);
+ replay(worker);
+ }
+
+ private void verifyAll() {
+ verify(config);
+ verify(env);
+ verify(transaction);
+ verify(worker);
+ }
+}
Property changes on: trunk/cachestore/bdbje/src/test/java/org/infinispan/loader/bdbje/PreparableTransactionRunnerTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:mergeinfo
+
Name: svn:eol-style
+ LF
More information about the infinispan-commits
mailing list