package org.multiverse.stms.gamma.transactionalobjects.baseGammaTxnRef; import org.junit.Before; import org.junit.Test; import org.multiverse.api.LockMode; import org.multiverse.api.functions.LongFunction; import org.multiverse.stms.gamma.GammaConstants; import org.multiverse.stms.gamma.GammaStm; import org.multiverse.stms.gamma.transactionalobjects.GammaTxnLong; import org.multiverse.stms.gamma.transactionalobjects.Tranlocal; import org.multiverse.stms.gamma.transactions.GammaTxn; import static org.junit.Assert.*; import static org.mockito.Mockito.mock; import static org.multiverse.stms.gamma.GammaTestUtils.*; public class ReleaseAfterFailureTest implements GammaConstants { private GammaStm stm; @Before public void setUp() { stm = new GammaStm(); } // ================================ misc ========================== @Test public void writeBiased_whenCommuting() { long initialValue = 10; GammaTxnLong ref = new GammaTxnLong(stm, initialValue); long initialVersion = ref.getVersion(); GammaTxn tx = stm.newDefaultTxn(); LongFunction function = mock(LongFunction.class); ref.commute(tx, function); Tranlocal tranlocal = tx.getRefTranlocal(ref); ref.releaseAfterFailure(tranlocal, tx.pool); assertRefHasNoLocks(ref); assertNull(tranlocal.owner); assertEquals(LOCKMODE_NONE, tranlocal.getLockMode()); assertNull(tranlocal.headCallable); assertVersionAndValue(ref, initialVersion, initialValue); } @Test public void writeBiased_whenRead() { writeBiased_whenRead(LockMode.None); writeBiased_whenRead(LockMode.Read); writeBiased_whenRead(LockMode.Write); writeBiased_whenRead(LockMode.Exclusive); } public void writeBiased_whenRead(LockMode lockMode) { GammaTxnLong ref = new GammaTxnLong(stm); GammaTxn tx = stm.newDefaultTxn(); Tranlocal tranlocal = ref.openForRead(tx, lockMode.asInt()); ref.releaseAfterFailure(tranlocal, tx.pool); assertNull(tranlocal.owner); assertFalse(tranlocal.hasDepartObligation); assertEquals(LOCKMODE_NONE, tranlocal.lockMode); assertSurplus(ref, 0); assertLockMode(ref, LockMode.None); assertWriteBiased(ref); assertReadonlyCount(ref, 0); } @Test public void writeBiased_whenWrite() { writeBiased_whenWrite(LockMode.None); writeBiased_whenWrite(LockMode.Read); writeBiased_whenWrite(LockMode.Write); writeBiased_whenWrite(LockMode.Exclusive); } public void writeBiased_whenWrite(LockMode lockMode) { GammaTxnLong ref = new GammaTxnLong(stm); GammaTxn tx = stm.newDefaultTxn(); Tranlocal tranlocal = ref.openForWrite(tx, lockMode.asInt()); tranlocal.isDirty = true; ref.releaseAfterFailure(tranlocal, tx.pool); assertNull(tranlocal.owner); assertFalse(tranlocal.hasDepartObligation); assertEquals(LOCKMODE_NONE, tranlocal.lockMode); assertSurplus(ref, 0); assertLockMode(ref, LockMode.None); assertWriteBiased(ref); assertReadonlyCount(ref, 0); } // ========================= read biased ================================ @Test public void readBiased_whenCommuting() { long initialValue = 10; GammaTxnLong ref = new GammaTxnLong(stm, initialValue); long initialVersion = ref.getVersion(); GammaTxn tx = stm.newDefaultTxn(); LongFunction function = mock(LongFunction.class); ref.commute(tx, function); Tranlocal tranlocal = tx.getRefTranlocal(ref); ref.releaseAfterFailure(tranlocal, tx.pool); assertRefHasNoLocks(ref); assertNull(tranlocal.owner); assertEquals(LOCKMODE_NONE, tranlocal.getLockMode()); assertNull(tranlocal.headCallable); assertVersionAndValue(ref, initialVersion, initialValue); } @Test public void readBiased_whenRead() { readBiased_whenRead(true,LockMode.None); readBiased_whenRead(true,LockMode.Read); readBiased_whenRead(true,LockMode.Write); readBiased_whenRead(true,LockMode.Exclusive); readBiased_whenRead(false,LockMode.None); readBiased_whenRead(false,LockMode.Read); readBiased_whenRead(false,LockMode.Write); readBiased_whenRead(false,LockMode.Exclusive); } public void readBiased_whenRead(boolean additionalSurplus, LockMode lockMode) { GammaTxnLong ref = makeReadBiased(new GammaTxnLong(stm)); if(additionalSurplus){ ref.arrive(1); } GammaTxn tx = newArrivingTransaction(stm); Tranlocal tranlocal = ref.openForRead(tx, lockMode.asInt()); ref.releaseAfterFailure(tranlocal, tx.pool); assertNull(tranlocal.owner); assertFalse(tranlocal.hasDepartObligation); assertEquals(LOCKMODE_NONE, tranlocal.lockMode); assertSurplus(ref, 1); assertLockMode(ref, LockMode.None); assertReadBiased(ref); assertReadonlyCount(ref, 0); } @Test public void readBiased_whenWrite() { readBiased_whenWrite(false,LockMode.None); readBiased_whenWrite(false,LockMode.Read); readBiased_whenWrite(false,LockMode.Write); readBiased_whenWrite(false,LockMode.Exclusive); readBiased_whenWrite(true,LockMode.None); readBiased_whenWrite(true,LockMode.Read); readBiased_whenWrite(true,LockMode.Write); readBiased_whenWrite(true,LockMode.Exclusive); } public void readBiased_whenWrite(boolean additionalSurplus, LockMode lockMode) { GammaTxnLong ref = makeReadBiased(new GammaTxnLong(stm)); if(additionalSurplus){ ref.arrive(1); } GammaTxn tx = newArrivingTransaction(stm); Tranlocal tranlocal = ref.openForWrite(tx, lockMode.asInt()); tranlocal.isDirty = true; ref.releaseAfterFailure(tranlocal, tx.pool); assertNull(tranlocal.owner); assertFalse(tranlocal.hasDepartObligation); assertEquals(LOCKMODE_NONE, tranlocal.lockMode); assertSurplus(ref, 1); assertLockMode(ref, LockMode.None); assertReadBiased(ref); assertReadonlyCount(ref, 0); } // ================================ misc ========================== @Test public void whenConstructing() { GammaTxn tx = stm.newDefaultTxn(); GammaTxnLong ref = new GammaTxnLong(tx, 0); Tranlocal tranlocal = tx.locate(ref); ref.releaseAfterFailure(tranlocal, tx.pool); assertNull(tranlocal.owner); assertFalse(tranlocal.hasDepartObligation); assertEquals(LOCKMODE_NONE, tranlocal.lockMode); assertSurplus(ref, 1); assertLockMode(ref, LockMode.Exclusive); assertWriteBiased(ref); assertReadonlyCount(ref, 0); } }