package org.multiverse.stms.gamma; import org.junit.Before; import org.junit.Test; import org.multiverse.api.*; import org.multiverse.api.exceptions.IllegalTxnFactoryException; import org.multiverse.api.lifecycle.TxnListener; import org.multiverse.stms.gamma.transactions.GammaTxn; import org.multiverse.stms.gamma.transactions.GammaTxnConfig; import org.multiverse.stms.gamma.transactions.GammaTxnFactory; import org.multiverse.stms.gamma.transactions.GammaTxnFactoryBuilder; import org.multiverse.stms.gamma.transactions.fat.FatMonoGammaTxn; import java.util.List; import static java.util.Arrays.asList; import static org.junit.Assert.*; import static org.mockito.Mockito.mock; public class GammaStm_txnFactoryBuilderTest implements GammaConstants{ private GammaStm stm; @Before public void setUp() { stm = new GammaStm(); } @Test public void whenDefaultTransactionFactory() { GammaTxnConfig config = new GammaTxnConfig(stm); config.init(); assertEquals(IsolationLevel.Snapshot, config.isolationLevel); assertFalse(config.isInterruptible()); assertFalse(config.isReadonly()); assertEquals(LockMode.None, config.readLockMode); assertEquals(LockMode.None, config.writeLockMode); assertTrue(config.dirtyCheck); assertSame(stm, config.getStm()); assertSame(stm.getGlobalConflictCounter(), config.getGlobalConflictCounter()); assertTrue(config.trackReads); assertTrue(config.blockingAllowed); assertEquals(1000, config.maxRetries); assertTrue(config.isSpeculative()); assertTrue(config.isAnonymous); assertSame(DefaultBackoffPolicy.MAX_100_MS, config.getBackoffPolicy()); assertEquals(Long.MAX_VALUE, config.getTimeoutNs()); assertSame(TraceLevel.None, config.getTraceLevel()); assertTrue(config.writeSkewAllowed); assertEquals(PropagationLevel.Requires, config.getPropagationLevel()); assertTrue(config.getPermanentListeners().isEmpty()); } @Test(expected = NullPointerException.class) public void whenNullPermanentListener_thenNullPointerException() { stm.newTxnFactoryBuilder().addPermanentListener(null); } @Test public void whenPermanentListenerAdded() { GammaTxnFactoryBuilder oldBuilder = stm.newTxnFactoryBuilder(); TxnListener listener = mock(TxnListener.class); GammaTxnFactoryBuilder newBuilder = oldBuilder.addPermanentListener(listener); assertEquals(asList(listener), newBuilder.getConfig().getPermanentListeners()); assertTrue(oldBuilder.getConfig().getPermanentListeners().isEmpty()); } @Test public void whenPermanentListenerAdded_thenNoCheckForDuplicates() { GammaTxnFactoryBuilder oldBuilder = stm.newTxnFactoryBuilder(); TxnListener listener = mock(TxnListener.class); GammaTxnFactoryBuilder newBuilder = oldBuilder.addPermanentListener(listener) .addPermanentListener(listener); assertEquals(asList(listener, listener), newBuilder.getConfig().getPermanentListeners()); } @Test public void whenNoPermanentListenersAdded_thenEmptyList() { GammaTxnFactoryBuilder builder = stm.newTxnFactoryBuilder(); assertTrue(builder.getConfig().getPermanentListeners().isEmpty()); } @Test public void whenMultipleListenersAdded_thenTheyAreAddedInOrder() { TxnListener listener1 = mock(TxnListener.class); TxnListener listener2 = mock(TxnListener.class); GammaTxnFactoryBuilder builder = stm.newTxnFactoryBuilder() .addPermanentListener(listener1) .addPermanentListener(listener2); List<TxnListener> listeners = builder.getConfig().getPermanentListeners(); assertEquals(asList(listener1, listener2), listeners); } @Test public void whenGetPermanentListenersCalled_immutableListReturned() { GammaTxnFactoryBuilder builder = stm.newTxnFactoryBuilder() .addPermanentListener(mock(TxnListener.class)) .addPermanentListener(mock(TxnListener.class)); List<TxnListener> listeners = builder.getConfig().getPermanentListeners(); try { listeners.clear(); fail(); } catch (UnsupportedOperationException e) { } } @Test public void whenReadLockModeOverridesWriteLockMode() { whenReadLockModeOverridesWriteLockMode(LockMode.None, LockMode.None); whenReadLockModeOverridesWriteLockMode(LockMode.None, LockMode.Read); whenReadLockModeOverridesWriteLockMode(LockMode.None, LockMode.Write); whenReadLockModeOverridesWriteLockMode(LockMode.None, LockMode.Exclusive); whenReadLockModeOverridesWriteLockMode(LockMode.Read, LockMode.None); whenReadLockModeOverridesWriteLockMode(LockMode.Read, LockMode.Read); whenReadLockModeOverridesWriteLockMode(LockMode.Read, LockMode.Write); whenReadLockModeOverridesWriteLockMode(LockMode.Read, LockMode.Exclusive); whenReadLockModeOverridesWriteLockMode(LockMode.Write, LockMode.None); whenReadLockModeOverridesWriteLockMode(LockMode.Write, LockMode.Read); whenReadLockModeOverridesWriteLockMode(LockMode.Write, LockMode.Write); whenReadLockModeOverridesWriteLockMode(LockMode.Write, LockMode.Exclusive); whenReadLockModeOverridesWriteLockMode(LockMode.Exclusive, LockMode.None); whenReadLockModeOverridesWriteLockMode(LockMode.Exclusive, LockMode.Read); whenReadLockModeOverridesWriteLockMode(LockMode.Exclusive, LockMode.Write); whenReadLockModeOverridesWriteLockMode(LockMode.Exclusive, LockMode.Exclusive); } public void whenReadLockModeOverridesWriteLockMode(LockMode readLockMode, LockMode writeLockMode) { GammaTxnFactory txFactory = stm.newTxnFactoryBuilder() .setWriteLockMode(writeLockMode) .setReadLockMode(readLockMode) .newTransactionFactory(); assertEquals(readLockMode, txFactory.getConfig().readLockMode); assertEquals(readLockMode.asInt(), txFactory.getConfig().readLockModeAsInt); if (readLockMode.asInt() > writeLockMode.asInt()) { assertEquals(readLockMode, txFactory.getConfig().getWriteLockMode()); assertEquals(readLockMode.asInt(), txFactory.getConfig().writeLockModeAsInt); } else { assertEquals(writeLockMode, txFactory.getConfig().getWriteLockMode()); assertEquals(writeLockMode.asInt(), txFactory.getConfig().writeLockModeAsInt); } } @Test public void whenWriteLockModeOverridesReadLockMode() { whenWriteLockModeOverridesReadLockMode(LockMode.None, LockMode.None, true); whenWriteLockModeOverridesReadLockMode(LockMode.None, LockMode.Read, true); whenWriteLockModeOverridesReadLockMode(LockMode.None, LockMode.Write, true); whenWriteLockModeOverridesReadLockMode(LockMode.None, LockMode.Exclusive, true); whenWriteLockModeOverridesReadLockMode(LockMode.Read, LockMode.None, false); whenWriteLockModeOverridesReadLockMode(LockMode.Read, LockMode.Read, true); whenWriteLockModeOverridesReadLockMode(LockMode.Read, LockMode.Write, true); whenWriteLockModeOverridesReadLockMode(LockMode.Read, LockMode.Exclusive, true); whenWriteLockModeOverridesReadLockMode(LockMode.Write, LockMode.None, false); whenWriteLockModeOverridesReadLockMode(LockMode.Write, LockMode.Read, false); whenWriteLockModeOverridesReadLockMode(LockMode.Write, LockMode.Write, true); whenWriteLockModeOverridesReadLockMode(LockMode.Write, LockMode.Exclusive, true); whenWriteLockModeOverridesReadLockMode(LockMode.Exclusive, LockMode.None, false); whenWriteLockModeOverridesReadLockMode(LockMode.Exclusive, LockMode.Read, false); whenWriteLockModeOverridesReadLockMode(LockMode.Exclusive, LockMode.Write, false); whenWriteLockModeOverridesReadLockMode(LockMode.Exclusive, LockMode.Exclusive, true); } public void whenWriteLockModeOverridesReadLockMode(LockMode readLock, LockMode writeLock, boolean success) { if (success) { GammaTxnFactory txFactory = stm.newTxnFactoryBuilder() .setReadLockMode(readLock) .setWriteLockMode(writeLock) .newTransactionFactory(); assertEquals(readLock, txFactory.getConfig().getReadLockMode()); assertEquals(writeLock, txFactory.getConfig().getWriteLockMode()); } else { try { stm.newTxnFactoryBuilder() .setReadLockMode(readLock) .setWriteLockMode(writeLock) .newTransactionFactory(); fail(); } catch (IllegalTxnFactoryException expected) { } } } @Test public void whenReadtrackingDisabled() { GammaTxnFactory txFactory = stm.newTxnFactoryBuilder() .setReadTrackingEnabled(false) .setBlockingAllowed(false) .newTransactionFactory(); assertFalse(txFactory.getConfig().isReadTrackingEnabled()); } @Test public void whenSpeculativeConfigEnabled() { GammaTxnFactory txFactory = stm.newTxnFactoryBuilder() .setDirtyCheckEnabled(false) .setSpeculative(true) .newTransactionFactory(); GammaTxnConfig configuration = txFactory.getConfig(); assertFalse(configuration.getSpeculativeConfiguration().fat); assertTrue(configuration.isSpeculative()); } @Test public void whenWriteSkewNotAllowed() { GammaTxnFactory txFactory = stm.newTxnFactoryBuilder() .setSpeculative(true) .setIsolationLevel(IsolationLevel.Serializable) .newTransactionFactory(); GammaTxnConfig configuration = txFactory.getConfig(); assertTrue(configuration.getSpeculativeConfiguration().fat); assertTrue(configuration.isSpeculative()); } @Test public void whenSerializedThenFatTransaction() { GammaTxnFactory txFactory = stm.newTxnFactoryBuilder() .setSpeculative(true) .setDirtyCheckEnabled(false) .setIsolationLevel(IsolationLevel.Serializable) .newTransactionFactory(); GammaTxn tx = txFactory.newTxn(); assertTrue(tx instanceof FatMonoGammaTxn); } @Test public void whenSnapshotIsolationLevelThenLeanTransaction() { GammaTxnFactory txFactory = stm.newTxnFactoryBuilder() .setSpeculative(true) .setDirtyCheckEnabled(false) .setIsolationLevel(IsolationLevel.Snapshot) .newTransactionFactory(); GammaTxn tx = txFactory.newTxn(); assertEquals(TRANSACTIONTYPE_LEAN_MONO, tx.transactionType); } @Test public void whenReadonlyThenFatTransaction() { GammaTxnFactory txFactory = stm.newTxnFactoryBuilder() .setSpeculative(true) .setReadonly(true) .setDirtyCheckEnabled(false) .newTransactionFactory(); GammaTxn tx = txFactory.newTxn(); assertEquals(TRANSACTIONTYPE_FAT_MONO,tx.transactionType); } }