001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tctest.spring.integrationtests.tests;
006:
007: import com.tc.test.server.appserver.deployment.AbstractTwoServerDeploymentTest;
008: import com.tc.test.server.appserver.deployment.DeploymentBuilder;
009: import com.tctest.spring.bean.ISharedLock;
010: import com.tctest.spring.integrationtests.SpringTwoServerTestSetup;
011:
012: import junit.framework.Test;
013:
014: /**
015: * This class is testing shared lock behavior
016: *
017: * <ol>
018: * <li> Trying to modify a shared object outside a shared lock should raise exception
019: * <li> Locking on shared object applies to the whole cluster
020: * <li> Shared value will not be propagated until execution thread exits the monitor
021: * </ol>
022: */
023: public class SharedLockTest extends AbstractTwoServerDeploymentTest {
024:
025: private static final String REMOTE_SERVICE_NAME = "SharedLock";
026: private static final String BEAN_DEFINITION_FILE_FOR_TEST = "classpath:/com/tctest/spring/beanfactory-sharedlock.xml";
027: private static final String CONFIG_FILE_FOR_TEST = "/tc-config-files/sharedlock-tc-config.xml";
028:
029: private ISharedLock sharedLock1;
030: private ISharedLock sharedLock2;
031:
032: protected void setUp() throws Exception {
033: super .setUp();
034:
035: sharedLock1 = (ISharedLock) server0.getProxy(ISharedLock.class,
036: REMOTE_SERVICE_NAME);
037: sharedLock2 = (ISharedLock) server1.getProxy(ISharedLock.class,
038: REMOTE_SERVICE_NAME);
039: }
040:
041: public void testSharedLock() throws Exception {
042: logger.debug("testing ShareLock");
043:
044: long id1 = sharedLock1.getLocalID();
045: long id2 = sharedLock2.getLocalID();
046:
047: assertTrue("Pre-condition is not satisfied - id1 - " + id1
048: + " - id2 - " + id2, id1 != id2);
049:
050: // test mutation w/o a lock
051: sharedLock1.unlockedMutate();
052: sharedLock2.unlockedMutate();
053:
054: LockAndMutate t1 = new LockAndMutate(sharedLock1);
055: LockAndMutate t2 = new LockAndMutate(sharedLock2);
056: t1.start();
057: t2.start();
058:
059: LockAndMutate loser = null;
060: LockAndMutate winner = null;
061: while (true) {
062: if (t1.wasFirst()) {
063: winner = t1;
064: break;
065: } else if (t2.wasFirst()) {
066: winner = t2;
067: break;
068: } else {
069: Thread.sleep(250);
070: }
071: }
072:
073: loser = (winner == t1) ? t2 : t1;
074: assertNotSame(winner, loser);
075:
076: // This sleep is unnecessary, but just used to help ferret out false positives
077: Thread.sleep(5000);
078:
079: assertFalse(loser.wasFirst());
080: assertTrue(winner.sharedLockHeld());
081: assertFalse(loser.sharedLockHeld());
082: assertNull(loser.getFirstHolder()); // This will be null for the loser since the winner has not yet committed
083:
084: winner.release();
085:
086: t1.join();
087: t2.join();
088:
089: assertEquals(new Long(winner.getLocalID()), loser
090: .getFirstHolder());
091:
092: logger.debug("!!!! Asserts passed !!!");
093: }
094:
095: private static class LockAndMutate extends Thread {
096:
097: private final ISharedLock lock;
098:
099: LockAndMutate(ISharedLock lock) {
100: this .lock = lock;
101: }
102:
103: public void run() {
104: lock.lockAndMutate();
105: }
106:
107: Long getFirstHolder() {
108: return lock.getFirstHolder();
109: }
110:
111: boolean wasFirst() {
112: return lock.isFirstHolder();
113: }
114:
115: boolean sharedLockHeld() {
116: return lock.sharedLockHeld();
117: }
118:
119: void release() {
120: lock.release();
121: }
122:
123: long getLocalID() {
124: return lock.getLocalID();
125: }
126:
127: }
128:
129: private static class SharedLockTestSetup extends
130: SpringTwoServerTestSetup {
131: private SharedLockTestSetup() {
132: super (SharedLockTest.class, CONFIG_FILE_FOR_TEST,
133: "test-sharedlock");
134: }
135:
136: protected void configureWar(DeploymentBuilder builder) {
137: builder
138: .addBeanDefinitionFile(BEAN_DEFINITION_FILE_FOR_TEST);
139: builder.addRemoteService(REMOTE_SERVICE_NAME, "sharedlock",
140: ISharedLock.class);
141: }
142: }
143:
144: public static Test suite() {
145: return new SharedLockTestSetup();
146: }
147:
148: }
|