/* * JBoss, Home of Professional Open Source * Copyright 2009 Red Hat Inc. and/or its affiliates and other * contributors as indicated by the @author tags. All rights reserved. * See the copyright.txt in the distribution for a full listing of * individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.infinispan.loaders.bdbje; import com.sleepycat.collections.CurrentTransaction; import com.sleepycat.collections.TransactionWorker; import com.sleepycat.je.Environment; import com.sleepycat.je.EnvironmentConfig; import com.sleepycat.je.LockConflictException; import com.sleepycat.je.LockTimeoutException; import com.sleepycat.je.Transaction; import com.sleepycat.je.TransactionConfig; import static org.mockito.Mockito.*; import com.sleepycat.je.txn.Locker; import org.infinispan.loaders.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 * @since 4.0 */ @Test(groups = "unit", enabled = true, testName = "loaders.bdbje.PreparableTransactionRunnerTest") public class PreparableTransactionRunnerTest { PreparableTransactionRunner runner; Environment env; EnvironmentConfig config; TransactionWorker worker; Transaction transaction; @BeforeMethod public void setUp() throws Exception { config = mock(EnvironmentConfig.class); when(config.getTransactional()).thenReturn(true); when(config.getLocking()).thenReturn(true); transaction = mock(Transaction.class); env = mock(Environment.class); when(env.getConfig()).thenReturn(config); when(env.beginTransaction(null, null)).thenReturn(transaction); worker = mock(TransactionWorker.class); } @AfterMethod public void tearDown() throws CacheLoaderException { runner = null; env = null; config = null; } @Test public void testMoreDeadlocks() throws Exception { Locker mockLocker = mock(Locker.class); doThrow(new LockTimeoutException(mockLocker, "")).when(worker).doWork(); when(env.beginTransaction(null, null)).thenReturn(transaction); runner = new PreparableTransactionRunner(env, 2, null); try { runner.prepare(worker); assert false : "should have gotten a deadlock exception"; } catch (LockTimeoutException e) { } } @Test public void testPrepare() throws Exception { worker.doWork(); runner = new PreparableTransactionRunner(env); runner.prepare(worker); } @Test public void testRun() throws Exception { transaction.commit(); worker.doWork(); runner = new PreparableTransactionRunner(env); runner.run(worker); } @Test public void testOneArgConstructorSetsCurrentTxn() throws Exception { runner = new PreparableTransactionRunner(env); assert CurrentTransaction.getInstance(env) == runner.currentTxn; } @Test public void testSetMaxRetries() throws Exception { runner = new PreparableTransactionRunner(env); runner.setMaxRetries(1); assert runner.getMaxRetries() == 1; } @Test public void testSetAllowNestedTransactions() throws Exception { 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 { TransactionConfig config = new TransactionConfig(); runner = new PreparableTransactionRunner(env); runner.setTransactionConfig(config); assert runner.getTransactionConfig().equals(config); } @Test public void testExceptionThrownInPrepare() throws Exception { doThrow(new RuntimeException()).when(worker).doWork(); runner = new PreparableTransactionRunner(env); try { runner.prepare(worker); assert false : "should have gotten an exception"; } catch (RuntimeException e) { } } @Test public void testErrorThrownInPrepare() throws Exception { doThrow(new Error()).when(worker).doWork(); runner = new PreparableTransactionRunner(env); try { runner.prepare(worker); assert false : "should have gotten an exception"; } catch (Error e) { } } @Test public void testExceptionThrownInRun() throws Exception { doThrow(new RuntimeException()).when(worker).doWork(); runner = new PreparableTransactionRunner(env); try { runner.prepare(worker); assert false : "should have gotten an exception"; } catch (RuntimeException e) { } } @Test public void testErrorThrownInRun() throws Exception { doThrow(new Error()).when(worker).doWork(); runner = new PreparableTransactionRunner(env); try { runner.run(worker); assert false : "should have gotten an exception"; } catch (Error e) { } } public void testRethrowIfNotDeadLockDoesntThrowWhenGivenDeadlockException() throws Exception { runner = new PreparableTransactionRunner(env); runner.rethrowIfNotDeadLock(mock(LockTimeoutException.class)); } public void testThrowableDuringAbort() throws Exception { doThrow(new RuntimeException()).when(transaction).abort(); 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; } }