package org.multiverse.stms.gamma;
import org.junit.Before;
import org.junit.Test;
import org.multiverse.api.TxnExecutor;
import org.multiverse.api.Txn;
import org.multiverse.api.callables.TxnLongCallable;
import org.multiverse.api.callables.TxnVoidCallable;
import org.multiverse.api.exceptions.TooManyRetriesException;
import org.multiverse.stms.gamma.transactionalobjects.GammaTxnLong;
import org.multiverse.stms.gamma.transactions.fat.FatMonoGammaTxn;
import static org.junit.Assert.*;
import static org.multiverse.api.TxnThreadLocal.clearThreadLocalTxn;
import static org.multiverse.api.TxnThreadLocal.getThreadLocalTxn;
public class GammaTxnExecutor_integrationTest implements GammaConstants {
private GammaStm stm;
@Before
public void setUp() {
stm = new GammaStm();
clearThreadLocalTxn();
}
@Test
public void whenRead() {
final GammaTxnLong ref = new GammaTxnLong(stm, 10);
TxnExecutor executor = stm.newTxnFactoryBuilder().newTxnExecutor();
long result = executor.execute(new TxnLongCallable() {
@Override
public long call(Txn tx) throws Exception {
assertSame(tx, getThreadLocalTxn());
return ref.get(tx);
}
});
assertNull(getThreadLocalTxn());
assertEquals(10, result);
}
@Test
public void whenUpdate() {
final GammaTxnLong ref = new GammaTxnLong(stm, 0);
TxnExecutor executor = stm.newTxnFactoryBuilder().newTxnExecutor();
executor.execute(new TxnVoidCallable() {
@Override
public void call(Txn tx) throws Exception {
ref.incrementAndGet(tx, 1);
}
});
assertEquals(1, ref.atomicGet());
}
@Test
public void whenTooManyRetries() {
final GammaTxnLong ref = new GammaTxnLong(stm);
FatMonoGammaTxn otherTx = new FatMonoGammaTxn(stm);
ref.openForWrite(otherTx, LOCKMODE_EXCLUSIVE);
try {
TxnExecutor executor = stm.newTxnFactoryBuilder()
.setMaxRetries(100)
.newTxnExecutor();
executor.execute(new TxnVoidCallable() {
@Override
public void call(Txn tx) throws Exception {
ref.get(tx);
}
});
fail();
} catch (TooManyRetriesException expected) {
expected.printStackTrace();
}
}
@Test
public void whenMultipleUpdatesDoneInSingleTransaction() {
final GammaTxnLong ref = new GammaTxnLong(stm);
TxnExecutor executor = stm.newTxnFactoryBuilder()
.setDirtyCheckEnabled(false)
.newTxnExecutor();
executor.execute(new TxnVoidCallable() {
@Override
public void call(Txn tx) throws Exception {
for (int k = 0; k < 10; k++) {
long l = ref.get();
ref.set(l + 1);
}
}
});
assertEquals(10, ref.atomicGet());
}
}