001: package org.jgroups.blocks;
002:
003: import java.lang.reflect.Constructor;
004: import java.lang.reflect.Field;
005: import java.util.HashMap;
006:
007: import junit.framework.Test;
008: import junit.framework.TestCase;
009: import junit.framework.TestSuite;
010: import org.jgroups.JChannel;
011:
012: /**
013: * Testcase for the DistributedLockManager
014: *
015: * @author Robert Schaffar-Taurok (robert@fusion.at)
016: * @version $Id: DistributedLockManagerTest.java,v 1.4 2006/04/05 05:35:54 belaban Exp $
017: */
018: public class DistributedLockManagerTest extends TestCase {
019:
020: public static final String SERVER_PROTOCOL_STACK = "UDP(mcast_addr=228.3.11.76;mcast_port=12345;ip_ttl=1;"
021: + "mcast_send_buf_size=150000;mcast_recv_buf_size=80000)"
022: // + "JMS(topicName=topic/testTopic;cf=UILConnectionFactory;"
023: // + "jndiCtx=org.jnp.interfaces.NamingContextFactory;"
024: // + "providerURL=localhost;ttl=10000)"
025: + ":PING(timeout=500;num_initial_members=1)"
026: + ":FD"
027: + ":VERIFY_SUSPECT(timeout=1500)"
028: + ":pbcast.NAKACK(gc_lag=50;retransmit_timeout=300,600,1200,2400,4800)"
029: + ":UNICAST(timeout=5000)"
030: + ":pbcast.STABLE(desired_avg_gossip=200)"
031: + ":FRAG(frag_size=4096)"
032: + ":pbcast.GMS(join_timeout=5000;join_retry_timeout=1000;"
033: + "shun=false;print_local_addr=false)"
034: // + ":SPEED_LIMIT(down_queue_limit=10)"
035: // + ":pbcast.STATE_TRANSFER(down_thread=false)"
036: ;
037:
038: public DistributedLockManagerTest(String testName) {
039: super (testName);
040: }
041:
042: public static Test suite() {
043: return new TestSuite(DistributedLockManagerTest.class);
044: }
045:
046: private JChannel channel1;
047: private JChannel channel2;
048:
049: protected VotingAdapter adapter1;
050: protected VotingAdapter adapter2;
051:
052: protected LockManager lockManager1;
053: protected LockManager lockManager2;
054:
055: protected static boolean logConfigured;
056:
057: public void setUp() throws Exception {
058: super .setUp();
059: channel1 = new JChannel(SERVER_PROTOCOL_STACK);
060: adapter1 = new VotingAdapter(channel1);
061: channel1.connect("voting");
062:
063: lockManager1 = new DistributedLockManager(adapter1, "1");
064:
065: // give some time for the channel to become a coordinator
066: try {
067: Thread.sleep(1000);
068: } catch (Exception ex) {
069: }
070:
071: channel2 = new JChannel(SERVER_PROTOCOL_STACK);
072: adapter2 = new VotingAdapter(channel2);
073: lockManager2 = new DistributedLockManager(adapter2, "2");
074:
075: channel2.connect("voting");
076:
077: try {
078: Thread.sleep(1000);
079: } catch (InterruptedException ex) {
080: }
081: }
082:
083: public void tearDown() throws Exception {
084: channel2.close();
085:
086: try {
087: Thread.sleep(1000);
088: } catch (InterruptedException ex) {
089: }
090:
091: channel1.close();
092: }
093:
094: public void test() throws Exception {
095: lockManager1.lock("obj1", "owner1", 10000);
096:
097: try {
098: lockManager1.lock("obj1", "owner2", 10000);
099: assertTrue("obj1 should not be locked.", false);
100: } catch (LockNotGrantedException ex) {
101: // everything is ok
102: }
103:
104: lockManager2.lock("obj2", "owner2", 1000);
105:
106: lockManager1.unlock("obj1", "owner1");
107:
108: try {
109: lockManager1.unlock("obj2", "owner1");
110: assertTrue("obj2 should not be released.", false);
111: } catch (LockNotReleasedException ex) {
112: // everything is ok
113: }
114:
115: lockManager1.unlock("obj2", "owner2");
116:
117: }
118:
119: public void testMultiLock() throws Exception {
120: lockManager1.lock("obj1", "owner1", 10000);
121:
122: // Override private members and simulate the errorcase which is, when two lockManagers have locked the same object
123: // This can happen after a merge
124: Class acquireLockDecreeClass = Class
125: .forName("org.jgroups.blocks.DistributedLockManager$AcquireLockDecree");
126: Constructor acquireLockDecreeConstructor = acquireLockDecreeClass
127: .getDeclaredConstructor(new Class[] { Object.class,
128: Object.class, Object.class });
129: acquireLockDecreeConstructor.setAccessible(true);
130: Object acquireLockDecree = acquireLockDecreeConstructor
131: .newInstance(new Object[] { "obj1", "owner2", "2" });
132:
133: Field heldLocksField = lockManager2.getClass()
134: .getDeclaredField("heldLocks");
135: heldLocksField.setAccessible(true);
136: HashMap heldLocks = (HashMap) heldLocksField.get(lockManager2);
137: heldLocks.put("obj1", acquireLockDecree);
138:
139: // Both lockManagers hold a lock on obj1 now
140:
141: try {
142: lockManager1.unlock("obj1", "owner1", true);
143: assertTrue(
144: "obj1 should throw a lockMultiLockedException upon release.",
145: false);
146: } catch (LockMultiLockedException e) {
147: // everything is ok
148: }
149:
150: try {
151: lockManager1.lock("obj1", "owner1", 10000);
152: assertTrue(
153: "obj1 should throw a LockNotGrantedException because it is still locked by lockManager2.",
154: false);
155: } catch (LockNotGrantedException e) {
156: // everything is ok
157: }
158:
159: try {
160: lockManager2.unlock("obj1", "owner2", true);
161: assertTrue(
162: "obj1 should throw a lockMultiLockedException upon release.",
163: false);
164: } catch (LockMultiLockedException e) {
165: // everything is ok
166: }
167:
168: // Everything should be unlocked now
169: try {
170: lockManager1.lock("obj1", "owner1", 10000);
171: } catch (LockNotGrantedException e) {
172: assertTrue("obj1 should be unlocked", false);
173: }
174:
175: lockManager1.unlock("obj1", "owner1", true);
176: }
177:
178: public static void main(String[] args) {
179: junit.textui.TestRunner.run(suite());
180: }
181: }
|