package org.multiverse.stms.gamma.transactionalobjects.refs; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.multiverse.api.LockMode; 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.assertFalse; import static org.junit.Assert.assertTrue; import static org.multiverse.TestUtils.assertOrecValue; import static org.multiverse.api.TxnThreadLocal.clearThreadLocalTxn; import static org.multiverse.stms.gamma.GammaTestUtils.*; public class HasReadConflictTest implements GammaConstants { private GammaStm stm; @Before public void setUp() { stm = new GammaStm(); clearThreadLocalTxn(); } @Test public void whenReadAndNoConflict() { GammaTxnLong ref = new GammaTxnLong(stm); GammaTxn tx = stm.newDefaultTxn(); Tranlocal read = ref.openForRead(tx, LOCKMODE_NONE); boolean hasReadConflict = ref.hasReadConflict(read); assertFalse(hasReadConflict); assertSurplus(ref, 0); assertRefHasNoLocks(ref); } @Test public void whenWriteAndNoConflict() { GammaTxnLong ref = new GammaTxnLong(stm); GammaTxn tx = stm.newDefaultTxn(); Tranlocal write = ref.openForWrite(tx, LOCKMODE_NONE); boolean hasReadConflict = ref.hasReadConflict(write); assertFalse(hasReadConflict); assertSurplus(ref, 0); assertRefHasNoLocks(ref); } @Test public void whenPrivatizedBySelf_thenNoConflict() { GammaTxnLong ref = new GammaTxnLong(stm); GammaTxn tx = stm.newDefaultTxn(); Tranlocal read = ref.openForRead(tx, LOCKMODE_EXCLUSIVE); boolean hasConflict = ref.hasReadConflict(read); assertFalse(hasConflict); assertSurplus(ref, 1); assertRefHasExclusiveLock(ref, tx); } @Test public void whenEnsuredBySelf_thenNoConflict() { GammaTxnLong ref = new GammaTxnLong(stm); GammaTxn tx = stm.newDefaultTxn(); Tranlocal read = ref.openForRead(tx, LOCKMODE_WRITE); boolean hasConflict = ref.hasReadConflict(read); assertFalse(hasConflict); assertSurplus(ref, 1); assertRefHasWriteLock(ref, tx); } @Test public void whenUpdatedByOther_thenConflict() { GammaTxnLong ref = new GammaTxnLong(stm); GammaTxn tx = stm.newDefaultTxn(); Tranlocal read = ref.openForRead(tx, LOCKMODE_NONE); //conflicting update ref.atomicIncrementAndGet(1); boolean hasConflict = ref.hasReadConflict(read); assertTrue(hasConflict); assertSurplus(ref, 0); assertRefHasNoLocks(ref); } @Test public void whenFresh() { GammaTxn tx = stm.newDefaultTxn(); GammaTxnLong ref = new GammaTxnLong(tx); Tranlocal tranlocal = tx.locate(ref); long orecValue = ref.orec; boolean conflict = ref.hasReadConflict(tranlocal); assertFalse(conflict); assertOrecValue(ref, orecValue); } @Test public void whenValueChangedByOtherAndLockedForCommitByOther() { GammaTxnLong ref = new GammaTxnLong(stm); GammaTxn tx = stm.newDefaultTxn(); Tranlocal read = ref.openForRead(tx, LOCKMODE_NONE); //do the conflicting update ref.atomicIncrementAndGet(1); //privatize it GammaTxn otherTx = stm.newDefaultTxn(); ref.getLock().acquire(otherTx, LockMode.Exclusive); boolean hasConflict = ref.hasReadConflict(read); assertTrue(hasConflict); assertSurplus(ref, 1); assertRefHasExclusiveLock(ref, otherTx); } @Test public void whenValueChangedByOtherAndEnsuredAgain() { GammaTxnLong ref = new GammaTxnLong(stm); GammaTxn tx = stm.newDefaultTxn(); Tranlocal read = ref.openForRead(tx, LOCKMODE_NONE); //do the conflicting update ref.atomicIncrementAndGet(1); //ensure it. GammaTxn otherTx = stm.newDefaultTxn(); ref.getLock().acquire(otherTx, LockMode.Write); boolean hasConflict = ref.hasReadConflict(read); assertTrue(hasConflict); assertSurplus(ref, 1); assertRefHasWriteLock(ref, otherTx); } @Test public void whenUpdateInProgressBecauseLockedByOther() { GammaTxnLong ref = new GammaTxnLong(stm); GammaTxn tx = stm.newDefaultTxn(); Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_NONE); GammaTxn otherTx = stm.newDefaultTxn(); ref.openForRead(otherTx, LOCKMODE_EXCLUSIVE); boolean hasReadConflict = ref.hasReadConflict(tranlocal); assertTrue(hasReadConflict); } @Test public void whenAlsoReadByOther_thenNoConflict() { GammaTxnLong ref = new GammaTxnLong(stm); GammaTxn tx = stm.newDefaultTxn(); ref.get(tx); GammaTxn otherTx = stm.newDefaultTxn(); Tranlocal read = ref.openForRead(otherTx, LOCKMODE_NONE); boolean hasConflict = ref.hasReadConflict(read); assertFalse(hasConflict); assertSurplus(ref, 0); assertRefHasNoLocks(ref); } @Test public void whenPendingUpdateByOther_thenNoConflict() { GammaTxnLong ref = new GammaTxnLong(stm); GammaTxn tx = stm.newDefaultTxn(); ref.set(tx, 200); GammaTxn otherTx = stm.newDefaultTxn(); Tranlocal read = ref.openForRead(otherTx, LOCKMODE_NONE); boolean hasConflict = ref.hasReadConflict(read); assertFalse(hasConflict); assertSurplus(ref, 0); assertRefHasNoLocks(ref); } @Test @Ignore public void whenReadBiased() { } }