Index: ssts-web/src/test/java/test/forgon/system/concurrent/service/OptimisticLockManagerTest.java =================================================================== diff -u --- ssts-web/src/test/java/test/forgon/system/concurrent/service/OptimisticLockManagerTest.java (revision 0) +++ ssts-web/src/test/java/test/forgon/system/concurrent/service/OptimisticLockManagerTest.java (revision 23798) @@ -0,0 +1,466 @@ +/** + * + */ +package test.forgon.system.concurrent.service; + +import static org.testng.Assert.assertEquals; + +import java.util.LinkedList; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; +import org.testng.annotations.Test; + +import test.forgon.disinfectsystem.AbstractCSSDTest; + +import com.forgon.system.concurrent.model.OptimisticLock; +import com.forgon.system.concurrent.model.OptimisticLockNoTransactionException; +import com.forgon.system.concurrent.service.OptimisticLockManager; +import com.forgon.system.concurrent.service.test.OptimisticLockManagerTest.WaitObject; +import com.forgon.system.concurrent.service.test.OptimisticLockManagerTestLevel1; + +import edu.emory.mathcs.backport.java.util.Arrays; +import edu.emory.mathcs.backport.java.util.Collections; + +/** + * @author dandan 2018年7月21日 下午7:42:30 + * + */ +@Transactional(propagation = Propagation.NEVER) +@Test(singleThreaded = true) +public class OptimisticLockManagerTest extends AbstractCSSDTest { + + private static final String ENTITY_OPTIMISTICLOCKTEST = "OptimisticLockTest"; + @Autowired + private OptimisticLockManager optimisticLockManager; + @Autowired + private OptimisticLockManagerTestLevel1 optimisticLockManagerTestLevel1; + + public void setOptimisticLockManager( + OptimisticLockManager optimisticLockManager) { + this.optimisticLockManager = optimisticLockManager; + } + + public void setOptimisticLockManagerTestLevel1( + OptimisticLockManagerTestLevel1 optimisticLockManagerTestLevel1) { + this.optimisticLockManagerTestLevel1 = optimisticLockManagerTestLevel1; + } + + /** + * 没有事务时报错 + * + */ + @Test(expectedExceptions = OptimisticLockNoTransactionException.class) + public void test_requestLockById_NoTransaction() { + optimisticLockManagerTestLevel1.requestLockById_TRANS_NEVER( + ENTITY_OPTIMISTICLOCKTEST, "1", null, null); + } + + /** + * 没有事务时报错 + * + */ + @Test(expectedExceptions = OptimisticLockNoTransactionException.class) + public void test_requestLockByStringIds_NoTransaction() { + + List ids = Arrays + .asList(new String[] { "1", "2", "3", "4", "5" }); + optimisticLockManagerTestLevel1.requestLockByStringIds_TRANS_NEVER( + ENTITY_OPTIMISTICLOCKTEST, ids, null, null); + } + + /** + * 一个事务请求锁_测试资源是否正确分配和释放 + */ + @Test + public void test_OneTransaction_Normal() { + { + WaitObject notifyObject = new WaitObject(); + WaitObject continueObject = new WaitObject(); + Thread thread = new Thread() { + public void run() { + optimisticLockManagerTestLevel1.requestLockById( + ENTITY_OPTIMISTICLOCKTEST, "1", notifyObject, + continueObject); + }; + }; + thread.start(); + notifyObject.waitForDone(); + List allLocks = optimisticLockManager.getAllLocks(); + assertEquals(allLocks.size(), 1); + OptimisticLock optimisticLock = allLocks.get(0); + assertEquals(optimisticLock.getEntity(), ENTITY_OPTIMISTICLOCKTEST); + assertEquals(optimisticLock.getId(), "1"); + + continueObject.setDone(); + try { + thread.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + List allLocks_end = optimisticLockManager + .getAllLocks(); + assertEquals(allLocks_end.size(), 0); + } + + } + + /** + * 一个事务请求锁_测试资源是否正确分配和释放 + */ + @Test + public void test_requestLockByStringIds_OneTransaction_Normal() { + { + List ids = Arrays + .asList(new String[] { "1", "2", "3", "4", "5" }); + WaitObject notifyObject = new WaitObject(); + WaitObject continueObject = new WaitObject(); + Thread thread = new Thread() { + public void run() { + optimisticLockManagerTestLevel1.requestLockByStringIds( + ENTITY_OPTIMISTICLOCKTEST, ids, notifyObject, + continueObject); + }; + }; + thread.start(); + notifyObject.waitForDone(); + List allLocks = optimisticLockManager.getAllLocks(); + assertEquals(allLocks.size(), ids.size()); + for(int i=0;i allLocks_end = optimisticLockManager + .getAllLocks(); + assertEquals(allLocks_end.size(), 0); + } + + } + + /** + * 一个事务重复请求锁 + */ + @Test + public void test_requestLockById_OneTransaction_RepeatRequest() { + { + WaitObject notifyObject = new WaitObject(); + WaitObject continueObject = new WaitObject(); + optimisticLockManagerTestLevel1.test_OneTransaction_RepeatRequest( + ENTITY_OPTIMISTICLOCKTEST, "1", null, null); + List allLocks_end = optimisticLockManager + .getAllLocks(); + assertEquals(allLocks_end.size(), 0); + } + } + + /** + * 一个事务重复请求锁 + */ + @Test + public void test_requestLockByStringIds_OneTransaction_RepeatRequest() { + { + WaitObject notifyObject = new WaitObject(); + WaitObject continueObject = new WaitObject(); + List ids = Arrays + .asList(new String[] { "1", "2", "3", "4", "5" }); + optimisticLockManagerTestLevel1 + .test_requestLockByStringIds_OneTransaction_RepeatRequest( + ENTITY_OPTIMISTICLOCKTEST, ids, null, null); + List allLocks_end = optimisticLockManager + .getAllLocks(); + assertEquals(allLocks_end.size(), 0); + } + } + + /** + * 两个事务请求锁_测试资源是否正确分配和释放 + */ + @Test + public void test_TwoTransactions_Normal() { + { + WaitObject notifyObject = new WaitObject(); + WaitObject continueObject = new WaitObject(); + Thread thread = new Thread() { + public void run() { + optimisticLockManagerTestLevel1.requestLockById( + ENTITY_OPTIMISTICLOCKTEST, "1", notifyObject, + continueObject); + }; + }; + thread.start(); + WaitObject notifyObject2 = new WaitObject(); + WaitObject continueObject2 = new WaitObject(); + Thread thread2 = new Thread() { + public void run() { + optimisticLockManagerTestLevel1.requestLockById( + ENTITY_OPTIMISTICLOCKTEST, "2", notifyObject2, + continueObject2); + }; + }; + notifyObject.waitForDone(); + { + List allLocks = optimisticLockManager + .getAllLocks(); + assertEquals(allLocks.size(), 1); + OptimisticLock optimisticLock = allLocks.get(0); + assertEquals(optimisticLock.getEntity(), + ENTITY_OPTIMISTICLOCKTEST); + assertEquals(optimisticLock.getId(), "1"); + } + + thread2.start(); + notifyObject2.waitForDone(); + { + List allLocks = optimisticLockManager + .getAllLocks(); + assertEquals(allLocks.size(), 2); + Collections.sort(allLocks, OptimisticLock.ID_COMPARATOR); + OptimisticLock optimisticLock = allLocks.get(0); + assertEquals(optimisticLock.getEntity(), + ENTITY_OPTIMISTICLOCKTEST); + assertEquals(optimisticLock.getId(), "1"); + + OptimisticLock optimisticLock1 = allLocks.get(1); + assertEquals(optimisticLock1.getEntity(), + ENTITY_OPTIMISTICLOCKTEST); + assertEquals(optimisticLock1.getId(), "2"); + } + continueObject.setDone(); + try { + thread.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + { + List allLocks = optimisticLockManager + .getAllLocks(); + assertEquals(allLocks.size(), 1); + OptimisticLock optimisticLock = allLocks.get(0); + assertEquals(optimisticLock.getEntity(), + ENTITY_OPTIMISTICLOCKTEST); + assertEquals(optimisticLock.getId(), "2"); + } + + continueObject2.setDone(); + try { + thread2.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + List allLocks_end = optimisticLockManager + .getAllLocks(); + assertEquals(allLocks_end.size(), 0); + } + } + + /** + * 两个事务请求锁_测试资源是否正确分配和释放 + */ + @Test + public void test_requestLockByStringIds_TwoTransactions_Normal() { + { + List ids = Arrays + .asList(new String[] { "1", "2", "3", "4", "5" }); + List ids2 = Arrays + .asList(new String[] { "6", "7", "8", "9"}); + WaitObject notifyObject = new WaitObject(); + WaitObject continueObject = new WaitObject(); + Thread thread = new Thread() { + public void run() { + optimisticLockManagerTestLevel1.requestLockByStringIds( + ENTITY_OPTIMISTICLOCKTEST, ids, notifyObject, + continueObject); + }; + }; + thread.start(); + WaitObject notifyObject2 = new WaitObject(); + WaitObject continueObject2 = new WaitObject(); + Thread thread2 = new Thread() { + public void run() { + optimisticLockManagerTestLevel1.requestLockByStringIds( + ENTITY_OPTIMISTICLOCKTEST, ids2, notifyObject2, + continueObject2); + }; + }; + notifyObject.waitForDone(); + { + List allLocks = optimisticLockManager + .getAllLocks(); + assertEquals(allLocks.size(), ids.size()); + for(int i=0;i allLocks = optimisticLockManager + .getAllLocks(); + List idsTotal = new LinkedList(ids); + idsTotal.addAll(ids2); + assertEquals(allLocks.size(), idsTotal.size()); + for(int i=0;i allLocks = optimisticLockManager + .getAllLocks(); + assertEquals(allLocks.size(), ids2.size()); + for(int i=0;i allLocks_end = optimisticLockManager + .getAllLocks(); + assertEquals(allLocks_end.size(), 0); + } + } + + /** + * 两个实体,两个事务请求锁_测试资源是否正确分配和释放,多个 + */ + // @Test() + // public void test_TwoTransactions_Normal() { + // { + // WaitObject notifyObject = new WaitObject(); + // WaitObject continueObject = new WaitObject(); + // Thread thread = new Thread() { + // public void run() { + // optimisticLockManagerTestLevel1.requestLockById( + // ENTITY_OPTIMISTICLOCKTEST, "1", notifyObject, + // continueObject); + // }; + // }; + // thread.start(); + // WaitObject notifyObject2 = new WaitObject(); + // WaitObject continueObject2 = new WaitObject(); + // Thread thread2 = new Thread() { + // public void run() { + // optimisticLockManagerTestLevel1.requestLockById( + // ENTITY_OPTIMISTICLOCKTEST, "2", notifyObject2, + // continueObject2); + // }; + // }; + // notifyObject.waitForDone(); + // { + // List allLocks = optimisticLockManager + // .getAllLocks(); + // assertEquals(allLocks.size(), 1); + // OptimisticLock optimisticLock = allLocks.get(0); + // assertEquals(optimisticLock.getEntity(), + // ENTITY_OPTIMISTICLOCKTEST); + // assertEquals(optimisticLock.getId(), "1"); + // } + // + // thread2.start(); + // notifyObject2.waitForDone(); + // { + // List allLocks = optimisticLockManager + // .getAllLocks(); + // assertEquals(allLocks.size(), 2); + // Collections.sort(allLocks, OptimisticLock.ID_COMPARATOR); + // OptimisticLock optimisticLock = allLocks.get(0); + // assertEquals(optimisticLock.getEntity(), + // ENTITY_OPTIMISTICLOCKTEST); + // assertEquals(optimisticLock.getId(), "1"); + // + // OptimisticLock optimisticLock1 = allLocks.get(1); + // assertEquals(optimisticLock1.getEntity(), + // ENTITY_OPTIMISTICLOCKTEST); + // assertEquals(optimisticLock1.getId(), "2"); + // } + // continueObject.setDone(); + // try { + // thread.join(); + // } catch (InterruptedException e) { + // e.printStackTrace(); + // } + // { + // List allLocks = optimisticLockManager + // .getAllLocks(); + // assertEquals(allLocks.size(), 1); + // OptimisticLock optimisticLock = allLocks.get(0); + // assertEquals(optimisticLock.getEntity(), + // ENTITY_OPTIMISTICLOCKTEST); + // assertEquals(optimisticLock.getId(), "2"); + // } + // + // continueObject2.setDone(); + // try { + // thread2.join(); + // } catch (InterruptedException e) { + // e.printStackTrace(); + // } + // List allLocks_end = optimisticLockManager + // .getAllLocks(); + // assertEquals(allLocks_end.size(), 0); + // } + // } + + /** + * 两个事务请求锁_冲突 + */ +// @Test(expectedExceptions = OptimisticLockConflictException.class) + public void test_TwoTransactions_Conflict(String id) { + { + WaitObject notifyObject = new WaitObject(); + WaitObject continueObject = new WaitObject(); + Thread thread = new Thread() { + public void run() { + optimisticLockManagerTestLevel1.requestLockById( + ENTITY_OPTIMISTICLOCKTEST, "1", notifyObject, + continueObject); + }; + }; + thread.start(); + WaitObject notifyObject2 = new WaitObject(); + WaitObject continueObject2 = new WaitObject(); + + notifyObject.waitForDone(); + { + List allLocks = optimisticLockManager + .getAllLocks(); + assertEquals(allLocks.size(), 1); + OptimisticLock optimisticLock = allLocks.get(0); + assertEquals(optimisticLock.getEntity(), + ENTITY_OPTIMISTICLOCKTEST); + assertEquals(optimisticLock.getId(), "1"); + } + optimisticLockManagerTestLevel1.requestLockById( + ENTITY_OPTIMISTICLOCKTEST, "1", notifyObject2, + continueObject2); + // 异常 + } + } +}