package org.multiverse.stms.gamma; import org.junit.Before; import org.junit.Test; import org.multiverse.TestThread; import org.multiverse.api.Txn; import org.multiverse.api.TxnExecutor; import org.multiverse.api.callables.TxnVoidCallable; import org.multiverse.api.exceptions.RetryTimeoutException; import org.multiverse.stms.gamma.transactionalobjects.GammaTxnLong; import org.multiverse.stms.gamma.transactionalobjects.Tranlocal; import org.multiverse.stms.gamma.transactions.GammaTxn; import java.util.concurrent.TimeUnit; import static org.junit.Assert.assertEquals; import static org.multiverse.TestUtils.*; import static org.multiverse.api.StmUtils.retry; import static org.multiverse.api.TxnThreadLocal.clearThreadLocalTxn; public class GammaTxnExecutor_timeoutTest { private GammaStm stm; private GammaTxnLong ref; private long timeoutNs; @Before public void setUp() { clearThreadLocalTxn(); stm = new GammaStm(); ref = new GammaTxnLong(stm); timeoutNs = TimeUnit.SECONDS.toNanos(2); } @Test public void whenTimeout() throws InterruptedException { TxnExecutor executor = stm.newTxnFactoryBuilder() .setTimeoutNs(timeoutNs) .newTxnExecutor(); AwaitThread t = new AwaitThread(executor); t.setPrintStackTrace(false); t.start(); t.join(); t.assertFailedWithException(RetryTimeoutException.class); assertEquals(0, ref.atomicGet()); } @Test public void whenSuccess() { TxnExecutor executor = stm.newTxnFactoryBuilder() .setTimeoutNs(timeoutNs) .newTxnExecutor(); AwaitThread t = new AwaitThread(executor); t.setPrintStackTrace(false); t.start(); sleepMs(500); assertAlive(t); stm.getDefaultTxnExecutor().execute(new TxnVoidCallable() { @Override public void call(Txn tx) throws Exception { GammaTxn btx = (GammaTxn) tx; ref.openForWrite(btx, LOCKMODE_NONE).long_value = 1; } }); joinAll(t); assertNothingThrown(t); assertEquals(2, ref.atomicGet()); } @Test public void whenNoWaitingNeededAndZeroTimeout() { stm.getDefaultTxnExecutor().execute(new TxnVoidCallable() { @Override public void call(Txn tx) throws Exception { GammaTxn btx = (GammaTxn) tx; ref.openForWrite(btx, LOCKMODE_NONE).long_value = 1; } }); TxnExecutor executor = stm.newTxnFactoryBuilder() .setTimeoutNs(0) .newTxnExecutor(); AwaitThread t = new AwaitThread(executor); t.setPrintStackTrace(false); t.start(); joinAll(t); assertNothingThrown(t); assertEquals(2, ref.atomicGet()); } class AwaitThread extends TestThread { private final TxnExecutor executor; public AwaitThread(TxnExecutor executor) { this.executor = executor; } @Override public void doRun() throws Exception { executor.execute(new TxnVoidCallable() { @Override public void call(Txn tx) throws Exception { GammaTxn btx = (GammaTxn) tx; Tranlocal write = ref.openForWrite(btx, LOCKMODE_NONE); if (write.long_value == 0) { retry(); } write.long_value = 2; } }); } } }