package org.multiverse.stms.gamma.transactionalobjects.txnref; import org.junit.Before; import org.junit.Test; import org.multiverse.api.LockMode; import org.multiverse.api.exceptions.LockedException; import org.multiverse.stms.gamma.GammaStm; import org.multiverse.stms.gamma.GammaStmConfig; import org.multiverse.stms.gamma.transactionalobjects.GammaTxnRef; import org.multiverse.stms.gamma.transactions.GammaTxn; import static org.junit.Assert.assertSame; import static org.junit.Assert.fail; import static org.multiverse.TestUtils.assertOrecValue; import static org.multiverse.api.TxnThreadLocal.clearThreadLocalTxn; import static org.multiverse.stms.gamma.GammaTestUtils.*; import static org.multiverse.stms.gamma.transactionalobjects.AbstractGammaObject.setReadonlyCount; import static org.multiverse.stms.gamma.transactionalobjects.AbstractGammaObject.setSurplus; public class GammaTxnRef_atomicSetTest { private GammaStm stm; @Before public void setUp() { GammaStmConfig config = new GammaStmConfig(); config.maxRetries = 0; stm = new GammaStm(config); clearThreadLocalTxn(); } // =================== write biased ============================== @Test public void writeBiased_whenReadLocked_thenLockedException() { writeBiased_whenLocked_thenLockedException(LockMode.Read); } @Test public void writeBiased_whenWriteLocked_thenLockedException() { writeBiased_whenLocked_thenLockedException(LockMode.Write); } @Test public void writeBiased_whenExclusiveLocked_thenLockedException() { writeBiased_whenLocked_thenLockedException(LockMode.Exclusive); } public void writeBiased_whenLocked_thenLockedException(LockMode lockMode) { String initialValue = "foo"; GammaTxnRef<String> ref = new GammaTxnRef<String>(stm, initialValue); long initialVersion = ref.version; GammaTxn tx = stm.newDefaultTxn(); ref.getLock().acquire(tx, lockMode); long orecValue = ref.orec; long globalConflictCount = stm.globalConflictCounter.count(); try { ref.atomicSet("bar"); fail(); } catch (LockedException expected) { } assertOrecValue(ref, orecValue); assertGlobalConflictCount(stm, globalConflictCount); assertVersionAndValue(ref, initialVersion, initialValue); } @Test public void writeBiased_whenNoChange() { String initialValue = "foo"; GammaTxnRef<String> ref = new GammaTxnRef<String>(stm, initialValue); long initialVersion = ref.version; long orecValue = ref.orec; long globalConflictCount = stm.globalConflictCounter.count(); String result = ref.atomicSet(initialValue); assertSame(initialValue, result); assertOrecValue(ref, setReadonlyCount(orecValue, 1)); assertGlobalConflictCount(stm, globalConflictCount); assertVersionAndValue(ref, initialVersion, initialValue); } @Test public void writeBiased_whenNoSurplusOfReaders() { String initialValue = "foo"; GammaTxnRef<String> ref = new GammaTxnRef<String>(stm, initialValue); long initialVersion = ref.version; long orecValue = ref.orec; long globalConflictCount = stm.globalConflictCounter.count(); String newValue = "bar"; String result = ref.atomicSet(newValue); assertSame(newValue, result); assertOrecValue(ref, orecValue); assertGlobalConflictCount(stm, globalConflictCount); assertVersionAndValue(ref, initialVersion+1, newValue); } @Test public void writeBiased_whenSurplusOfReaders_thenGlobalConflictCounterIncreased() { String initialValue = "foo"; GammaTxnRef<String> ref = new GammaTxnRef<String>(stm, initialValue); long initialVersion = ref.version; ref.arrive(1); long orecValue = ref.orec; long globalConflictCount = stm.globalConflictCounter.count(); String newValue = "bar"; String result = ref.atomicSet(newValue); assertSame(newValue, result); assertOrecValue(ref, orecValue); assertGlobalConflictCount(stm, globalConflictCount+1); assertVersionAndValue(ref, initialVersion+1, newValue); } // =================== read biased ============================== @Test public void readBiased_whenReadLocked_thenLockedException() { readBiased_whenLocked_thenLockedException(LockMode.Read); } @Test public void readBiased_whenWriteLocked_thenLockedException() { readBiased_whenLocked_thenLockedException(LockMode.Write); } @Test public void readBiased_whenExclusiveLocked_thenLockedException() { readBiased_whenLocked_thenLockedException(LockMode.Exclusive); } public void readBiased_whenLocked_thenLockedException(LockMode lockMode) { String initialValue = "foo"; GammaTxnRef<String> ref = makeReadBiased(new GammaTxnRef<String>(stm, initialValue)); long initialVersion = ref.version; GammaTxn tx = stm.newDefaultTxn(); ref.getLock().acquire(tx, lockMode); long orecValue = ref.orec; long globalConflictCount = stm.globalConflictCounter.count(); try { ref.atomicSet("bar"); fail(); } catch (LockedException expected) { } assertOrecValue(ref, orecValue); assertGlobalConflictCount(stm, globalConflictCount); assertVersionAndValue(ref, initialVersion, initialValue); } @Test public void readBiased_whenNoChange() { String initialValue = "foo"; GammaTxnRef<String> ref = makeReadBiased(new GammaTxnRef<String>(stm, initialValue)); long initialVersion = ref.version; long orecValue = ref.orec; long globalConflictCount = stm.globalConflictCounter.count(); String result = ref.atomicSet(initialValue); System.out.println(ref.toDebugString()); assertSame(initialValue, result); assertOrecValue(ref, setSurplus(orecValue, 1)); assertGlobalConflictCount(stm, globalConflictCount); assertVersionAndValue(ref, initialVersion, initialValue); } @Test public void readBiased_whenNoSurplusOfReaders() { String initialValue = "foo"; GammaTxnRef<String> ref = makeReadBiased(new GammaTxnRef<String>(stm, initialValue)); long initialVersion = ref.version; long globalConflictCount = stm.globalConflictCounter.count(); String newValue = "bar"; String result = ref.atomicSet(newValue); System.out.println(ref.toDebugString()); assertSame(newValue, result); assertWriteBiased(ref); assertSurplus(ref, 0); assertReadonlyCount(ref, 0); assertLockMode(ref, LockMode.None); assertGlobalConflictCount(stm, globalConflictCount); assertVersionAndValue(ref, initialVersion+1, newValue); } @Test public void readBiased_whenSurplusOfReaders_thenGlobalConflictCounterIncreased() { String initialValue = "foo"; GammaTxnRef<String> ref = makeReadBiased(new GammaTxnRef<String>(stm, initialValue)); long initialVersion = ref.version; ref.arrive(1); long globalConflictCount = stm.globalConflictCounter.count(); String newValue = "bar"; String result = ref.atomicSet(newValue); System.out.println(ref.toDebugString()); assertSame(newValue, result); assertWriteBiased(ref); assertSurplus(ref, 0); assertReadonlyCount(ref, 0); assertLockMode(ref, LockMode.None); assertGlobalConflictCount(stm, globalConflictCount+1); assertVersionAndValue(ref, initialVersion+1, newValue); } }