/* * JBoss, Home of Professional Open Source * Copyright 2010 Red Hat Inc. and/or its affiliates and other * contributors as indicated by the @author tags. All rights reserved. * See the copyright.txt in the distribution for a full listing of * individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.infinispan.tx.dld; import org.infinispan.test.PerCacheExecutorThread; import org.infinispan.test.TestingUtil; import org.infinispan.util.concurrent.locks.DeadlockDetectingLockManager; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import javax.transaction.RollbackException; import javax.transaction.Status; import javax.transaction.SystemException; import static org.testng.Assert.assertEquals; public abstract class BaseDldPessimisticLockingTest extends BaseDldTest { protected PerCacheExecutorThread ex0; protected PerCacheExecutorThread ex1; protected DeadlockDetectingLockManager lm0; protected DeadlockDetectingLockManager lm1; @BeforeMethod(alwaysRun=true) public void beforeMethod() { ex0 = new PerCacheExecutorThread(cache(0), 0); ex1 = new PerCacheExecutorThread(cache(1), 1); lm0 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(0)); lm0.setExposeJmxStats(true); lm1 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(1)); lm1.setExposeJmxStats(true); } @AfterMethod(alwaysRun=true) public void afterMethod() { ex0.stopThread(); ex1.stopThread(); } protected void testSymmetricDld(Object k0, Object k1) throws SystemException { long start = System.currentTimeMillis(); log.trace("Here is where the test starts"); ex0.execute(PerCacheExecutorThread.Operations.BEGIN_TX); ex1.execute(PerCacheExecutorThread.Operations.BEGIN_TX); ex0.setKeyValue(k0, "v0_0"); assertEquals(ex0.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE), PerCacheExecutorThread.OperationsResult.PUT_KEY_VALUE_OK); ex1.setKeyValue(k1, "v1_1"); assertEquals(ex1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE), PerCacheExecutorThread.OperationsResult.PUT_KEY_VALUE_OK); assertKeyLockedCorrectly(k0); assertKeyLockedCorrectly(k1); log.trace("After first set of puts"); ex0.clearResponse(); ex1.clearResponse(); log.info("Here is where DLD happens"); ex1.setKeyValue(k0, "v0_1"); ex1.executeNoResponse(PerCacheExecutorThread.Operations.PUT_KEY_VALUE); ex0.setKeyValue(k1, "v1_0"); ex0.executeNoResponse(PerCacheExecutorThread.Operations.PUT_KEY_VALUE); ex0.waitForResponse(); ex1.waitForResponse(); final Object resp0 = ex0.lastResponse(); boolean b1 = resp0 instanceof Exception; final Object resp1 = ex1.lastResponse(); boolean b2 = resp1 instanceof Exception; assert xor(b1, b2) : "Both are " + (b1 || b2); assert xor(ex0.getOngoingTransaction().getStatus() == Status.STATUS_MARKED_ROLLBACK, ex1.getOngoingTransaction().getStatus() == Status.STATUS_MARKED_ROLLBACK); log.trace("About to commit transactions"); Object txOutcome1 = ex0.execute(PerCacheExecutorThread.Operations.COMMIT_TX); Object txOutcome2 = ex1.execute(PerCacheExecutorThread.Operations.COMMIT_TX); System.out.println("txOutcome2 = " + txOutcome1); System.out.println("txOutcome2 = " + txOutcome2); assert xor(txOutcome1 == PerCacheExecutorThread.OperationsResult.COMMIT_TX_OK, txOutcome2 == PerCacheExecutorThread.OperationsResult.COMMIT_TX_OK); assert xor(txOutcome1 instanceof RollbackException, txOutcome2 instanceof RollbackException); log.tracef("k0 is %s, \n k1 is %s", k0, k1); assert cache(0).get(k0) != null; assert cache(0).get(k1) != null; assert cache(1).get(k0) != null; assert cache(1).get(k1) != null; long totalDeadlocks = lm0.getTotalNumberOfDetectedDeadlocks() + lm1.getTotalNumberOfDetectedDeadlocks(); assert totalDeadlocks == 1 : "Expected 1 but received " + totalDeadlocks; System.out.println("Test took " + (System.currentTimeMillis() - start) + " millis."); } }