001: // $Id: Deadlock2Test.java,v 1.10 2006/05/13 08:48:38 belaban Exp $
002:
003: package org.jgroups.tests;
004:
005: import junit.framework.Test;
006: import junit.framework.TestCase;
007: import junit.framework.TestSuite;
008: import org.jgroups.Address;
009: import org.jgroups.JChannel;
010: import org.jgroups.blocks.GroupRequest;
011: import org.jgroups.blocks.MethodCall;
012: import org.jgroups.blocks.RpcDispatcher;
013: import org.jgroups.util.RspList;
014:
015: import java.util.Enumeration;
016: import java.util.Vector;
017:
018: /**
019: * Test the distributed RPC deadlock detection mechanism, using one or two channels.
020: *
021: * @author John Giorgiadis
022: * @author Ovidiu Feodorov <ovidiuf@users.sourceforge.net>
023: * *
024: * @version $Revision: 1.10 $
025: */
026: public class Deadlock2Test extends TestCase {
027:
028: private static boolean DEADLOCK_DETECTION = true;
029:
030: private String name = "Deadlock2Test";
031:
032: public Deadlock2Test(String name) {
033: super (name);
034: }
035:
036: /**
037: * Tests the deadlock resolution using self-calls on a single channel. The deadlock detection
038: * is turned on so the method call should go straight through. If there is a problem, JUnit will
039: * timeout.
040: *
041: * @throws Exception
042: */
043: public void testOneChannel() throws Exception {
044: JChannel channel = new JChannel();
045: ServerObject serverObject = new ServerObject("obj1");
046: RpcDispatcher disp = new RpcDispatcher(channel, null, null,
047: serverObject, DEADLOCK_DETECTION);
048: serverObject.setRpcDispatcher(disp);
049: channel.connect(name);
050: Address localAddress = channel.getLocalAddress();
051:
052: // call the nested group method on itself
053: MethodCall call = new MethodCall("outerMethod", new Object[0],
054: new Class[0]);
055: log("calling outerMethod() on all members");
056: RspList rspList = disp.callRemoteMethods(null, call,
057: GroupRequest.GET_ALL, 0);
058: log("results of outerMethod(): " + rspList);
059:
060: assertEquals(1, rspList.size());
061: assertEquals("outerMethod[innerMethod]", rspList
062: .getValue(localAddress));
063: assertTrue(rspList.isReceived(localAddress));
064: assertFalse(rspList.isSuspected(localAddress));
065:
066: channel.disconnect();
067: channel.close();
068:
069: }
070:
071: /**
072: * Tests the deadlock resolution using two different channels. The deadlock detection
073: * is turned on. It implements the following scenario:
074: *
075: * Channel1 Channel2
076: * | |
077: * + -------------------------------> outerMethod()
078: * | RPC
079: * | |
080: * | |
081: * | |
082: * | <-- innerMethod() <-----------------+ ---------+
083: * | | |
084: * | | <-- innerMethod()
085: *
086: * If there is a deadlock, JUnit will timeout and fail the test.
087: *
088: */
089: public void testTwoChannels() throws Throwable {
090: ServerObject obj1, obj2 = null;
091:
092: JChannel c1 = new JChannel();
093: obj1 = new ServerObject("obj1");
094: RpcDispatcher disp1 = new RpcDispatcher(c1, null, null, obj1,
095: DEADLOCK_DETECTION);
096: obj1.setRpcDispatcher(disp1);
097: c1.connect(name);
098:
099: JChannel c2 = new JChannel();
100: obj2 = new ServerObject("obj2");
101: RpcDispatcher disp2 = new RpcDispatcher(c2, null, null, obj2,
102: DEADLOCK_DETECTION);
103: obj2.setRpcDispatcher(disp2);
104: c2.connect(name);
105: Address localAddress2 = c2.getLocalAddress();
106:
107: try {
108: // call a point-to-point method on Member 2 that triggers a nested distributed RPC
109: MethodCall call = new MethodCall("outerMethod",
110: new Object[0], new Class[0]);
111: log("calling outerMethod() on " + localAddress2);
112: Object retval = disp1.callRemoteMethod(localAddress2, call,
113: GroupRequest.GET_ALL, 0);
114: log("results of outerMethod(): " + retval);
115: } finally {
116: c2.close();
117: c1.close();
118: }
119: }
120:
121: public void testTwoChannelsWithInitialMulticast() throws Exception {
122: ServerObject obj1, obj2 = null;
123:
124: JChannel c1 = new JChannel();
125: obj1 = new ServerObject("obj1");
126: RpcDispatcher disp1 = new RpcDispatcher(c1, null, null, obj1,
127: DEADLOCK_DETECTION);
128: obj1.setRpcDispatcher(disp1);
129: c1.connect(name);
130:
131: JChannel c2 = new JChannel();
132: obj2 = new ServerObject("obj2");
133: RpcDispatcher disp2 = new RpcDispatcher(c2, null, null, obj2,
134: DEADLOCK_DETECTION);
135: obj2.setRpcDispatcher(disp2);
136: c2.connect(name);
137:
138: Vector dests = new Vector();
139: dests.add(c1.getLocalAddress());
140: dests.add(c2.getLocalAddress());
141:
142: try {
143: // call a point-to-point method on Member 2 that triggers a nested distributed RPC
144: MethodCall call = new MethodCall("outerMethod",
145: new Object[0], new Class[0]);
146: log("calling outerMethod() on all members");
147: RspList rsps = disp1.callRemoteMethods(dests, call,
148: GroupRequest.GET_ALL, 0);
149: log("results of outerMethod():\n" + rsps);
150: assertEquals(2, rsps.size());
151: } finally {
152: c2.close();
153: c1.close();
154: }
155: }
156:
157: public static Test suite() {
158: TestSuite s = new TestSuite(Deadlock2Test.class);
159: return s;
160: }
161:
162: public static void main(String[] args) {
163: junit.textui.TestRunner.run(suite());
164: System.exit(0);
165: }
166:
167: static void log(String msg) {
168: System.out.println("[" + Thread.currentThread() + "] " + msg);
169: }
170:
171: public class ServerObject {
172: String myName;
173:
174: public ServerObject(String name) {
175: this .myName = name;
176: }
177:
178: private RpcDispatcher disp;
179:
180: /**
181: * The ServerObject keeps a reference to its dispatcher to be able to send nested group
182: * RPCs.
183: */
184: public void setRpcDispatcher(RpcDispatcher rpcDispatcher) {
185: this .disp = rpcDispatcher;
186: }
187:
188: public String outerMethod() {
189: log("**** outerMethod() received, calling innerMethod() on all members");
190: MethodCall call = new MethodCall("innerMethod",
191: new Object[0], new Class[0]);
192: // RspList rspList = disp.callRemoteMethods(null, call, GroupRequest.GET_ALL, 5000);
193: RspList rspList = disp.callRemoteMethods(null, call,
194: GroupRequest.GET_ALL, 0);
195: Vector results = rspList.getResults();
196: log("results of calling innerMethod():\n" + rspList);
197: StringBuffer sb = new StringBuffer("outerMethod[");
198: for (Enumeration e = results.elements(); e
199: .hasMoreElements();) {
200: String s = (String) e.nextElement();
201: sb.append(s);
202: if (e.hasMoreElements()) {
203: sb.append(";");
204: }
205: }
206: sb.append("]");
207: return sb.toString();
208: }
209:
210: public String innerMethod() {
211: log("**** innerMethod() received, returning result");
212: return "innerMethod";
213: }
214: }
215:
216: }
|