package org.corfudb.runtime.object.transactions; import org.corfudb.protocols.logprotocol.LogEntry; import org.corfudb.protocols.logprotocol.MultiObjectSMREntry; import org.corfudb.protocols.logprotocol.MultiSMREntry; import org.corfudb.protocols.logprotocol.SMREntry; import org.corfudb.protocols.wireprotocol.ILogData; import org.corfudb.runtime.exceptions.TransactionAbortedException; import org.corfudb.runtime.view.ObjectsView; import org.corfudb.runtime.view.stream.IStreamView; import org.junit.Test; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; /** * Created by mwei on 11/22/16. */ public class WriteAfterWriteTransactionContextTest extends AbstractTransactionContextTest { /** In a write after write transaction, concurrent modifications * with the same read timestamp should abort. */ @Override public void TXBegin() { WWTXBegin(); } @Test public void concurrentModificationsCauseAbort() { getRuntime().setTransactionLogging(true); getMap(); t(1, () -> write("k" , "v1")); t(1, this::WWTXBegin); t(2, this::WWTXBegin); t(1, () -> get("k")); t(2, () -> get("k")); t(1, () -> write("k" , "v2")); t(2, () -> write("k" , "v3")); t(1, this::TXEnd); t(2, this::TXEnd) .assertThrows() .isInstanceOf(TransactionAbortedException.class); assertThat(getMap()) .containsEntry("k", "v2") .doesNotContainEntry("k", "v3"); IStreamView txStream = getRuntime().getStreamsView() .get(ObjectsView.TRANSACTION_STREAM_ID); List<ILogData> txns = txStream.remainingUpTo(Long.MAX_VALUE); assertThat(txns).hasSize(1); assertThat(txns.get(0).getLogEntry(getRuntime()).getType()).isEqualTo (LogEntry.LogEntryType.MULTIOBJSMR); MultiObjectSMREntry tx1 = (MultiObjectSMREntry)txns.get(0).getLogEntry (getRuntime()); assertThat(tx1.getEntryMap().size()).isEqualTo(1); MultiSMREntry entryMap = tx1.getEntryMap().entrySet().iterator() .next().getValue(); assertThat(entryMap).isNotNull(); assertThat(entryMap.getUpdates().size()).isEqualTo(1); SMREntry smrEntry = entryMap.getUpdates().get(0); Object[] args = smrEntry.getSMRArguments(); assertThat(smrEntry.getSMRMethod()).isEqualTo("put"); assertThat((String) args[0]).isEqualTo("k"); assertThat((String) args[1]).isEqualTo("v2"); } }