001: // $Id: DisconnectTest.java,v 1.11 2006/10/23 16:16:20 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.JChannel;
009: import org.jgroups.Message;
010: import org.jgroups.MessageListener;
011: import org.jgroups.View;
012: import org.jgroups.tests.stack.Utilities;
013: import org.jgroups.blocks.PullPushAdapter;
014: import org.jgroups.util.Promise;
015:
016: /**
017: * Ensures that a disconnected channel reconnects correctly, for different
018: * stack configurations.
019: *
020: * @author Ovidiu Feodorov <ovidiu@feodorov.com>
021: * @author Bela Ban belaban@yahoo.com
022: * @version $Revision: 1.11 $
023: **/
024: public class DisconnectTest extends TestCase {
025:
026: private JChannel channel;
027: private int routerPort;
028:
029: public DisconnectTest(String name) {
030: super (name);
031: }
032:
033: public void setUp() throws Exception {
034: super .setUp();
035: }
036:
037: public void tearDown() throws Exception {
038: super .tearDown();
039: if (channel != null) {
040: channel.close();
041: channel = null;
042: }
043: }
044:
045: private String getTUNNELProps(int routerPort, int gossipPort) {
046: return "TUNNEL(router_host=127.0.0.1;router_port="
047: + routerPort
048: + "):"
049: + "PING(gossip_host=127.0.0.1;gossip_port="
050: + gossipPort
051: + "):"
052: + "FD:"
053: + "VERIFY_SUSPECT(timeout=1500;down_thread=false;up_thread=false):"
054: + "pbcast.NAKACK(gc_lag=100;retransmit_timeout=3000;"
055: + "down_thread=true;up_thread=true):"
056: + "pbcast.STABLE(desired_avg_gossip=20000;down_thread=false;"
057: + "up_thread=false):"
058: + "pbcast.GMS(join_timeout=50000;join_retry_timeout=2000;shun=false;"
059: + "print_local_addr=true;down_thread=true;up_thread=true)";
060: }
061:
062: /**
063: * Tests if the channel has a null local address after disconnect (using
064: * TUNNEL).
065: *
066: * TO_DO: uncomment or delete after clarifying the semantics of
067: * getLocalAddress() on a disconnected channel.
068: *
069: **/
070: public void testNullLocalAddress_TUNNEL() throws Exception {
071: try {
072: routerPort = Utilities.startGossipRouter();
073: String props = getTUNNELProps(routerPort, routerPort);
074: channel = new JChannel(props);
075: channel.connect("testgroup");
076: assertTrue(channel.getLocalAddress() != null);
077: channel.disconnect();
078: assertNull(channel.getLocalAddress());
079: } finally {
080: Utilities.stopGossipRouter();
081: }
082: }
083:
084: /**
085: * Tests connect-disconnect-connect sequence for a group with one member
086: * (using default configuration).
087: **/
088: public void testDisconnectConnectOne_Default() throws Exception {
089: channel = new JChannel();
090: channel.connect("testgroup1");
091: channel.disconnect();
092: channel.connect("testgroup2");
093: View view = channel.getView();
094: assertEquals(1, view.size());
095: assertTrue(view.containsMember(channel.getLocalAddress()));
096: }
097:
098: /**
099: * Tests connect-disconnect-connect sequence for a group with two members
100: * (using default configuration).
101: **/
102: public void testDisconnectConnectTwo_Default() throws Exception {
103: JChannel coordinator = new JChannel();
104: coordinator.connect("testgroup");
105: channel = new JChannel();
106: channel.connect("testgroup1");
107: channel.disconnect();
108: channel.connect("testgroup");
109: View view = channel.getView();
110: assertEquals(2, view.size());
111: assertTrue(view.containsMember(channel.getLocalAddress()));
112: assertTrue(view.containsMember(coordinator.getLocalAddress()));
113:
114: coordinator.close();
115: }
116:
117: /**
118: * Tests connect-disconnect-connect-send sequence for a group with two
119: * members, using the default stack configuration. Assumes that default
120: * configuration includes pbcast.NAKACK. Test case introduced before fixing
121: * pbcast.NAKACK bug, which used to leave pbcast.NAKACK in a broken state
122: * after DISCONNECT. Because of this problem, the channel couldn't be used
123: * to multicast messages.
124: **/
125: public void testDisconnectConnectSendTwo_Default() throws Exception {
126:
127: final Promise msgPromise = new Promise();
128: JChannel coordinator = new JChannel();
129: coordinator.connect("testgroup");
130: PullPushAdapter ppa = new PullPushAdapter(coordinator,
131: new PromisedMessageListener(msgPromise));
132: ppa.start();
133:
134: channel = new JChannel();
135: channel.connect("testgroup1");
136: channel.disconnect();
137: channel.connect("testgroup");
138:
139: channel.send(new Message(null, null, "payload"));
140:
141: Message msg = (Message) msgPromise.getResult(20000);
142: assertTrue(msg != null);
143: assertEquals("payload", msg.getObject());
144:
145: ppa.stop();
146: coordinator.close();
147: }
148:
149: /**
150: * Tests connect-disconnect-connect sequence for a group with one member
151: * (using TUNNEL).
152: **/
153: public void testDisconnectConnectOne_TUNNEL() throws Exception {
154: try {
155: routerPort = Utilities.startGossipRouter();
156: String props = getTUNNELProps(routerPort, routerPort);
157: channel = new JChannel(props);
158: channel.connect("testgroup1");
159: channel.disconnect();
160: channel.connect("testgroup2");
161: View view = channel.getView();
162: assertEquals(1, view.size());
163: assertTrue(view.containsMember(channel.getLocalAddress()));
164: } finally {
165: Utilities.stopGossipRouter();
166: }
167: }
168:
169: /**
170: * Tests connect-disconnect-connect sequence for a group with two members
171: * (using TUNNEL).
172: **/
173: public void testDisconnectConnectTwo_TUNNEL() throws Exception {
174: try {
175: routerPort = Utilities.startGossipRouter();
176: String props = getTUNNELProps(routerPort, routerPort);
177: // String props="tunnel.xml";
178: JChannel coordinator = new JChannel(props);
179: coordinator.connect("testgroup");
180: channel = new JChannel(props);
181: channel.connect("testgroup1");
182: channel.disconnect();
183: channel.connect("testgroup");
184:
185: Thread.sleep(1000);
186:
187: View view = channel.getView();
188: assertEquals(2, view.size());
189: assertTrue(view.containsMember(channel.getLocalAddress()));
190: assertTrue(view.containsMember(coordinator
191: .getLocalAddress()));
192:
193: coordinator.close();
194: } finally {
195: Utilities.stopGossipRouter();
196: }
197: }
198:
199: /**
200: * Tests connect-disconnect-connect-send sequence for a group with two
201: * members, using TUNNEL. Test case introduced before fixing pbcast.NAKACK
202: * bug, which used to leave pbcast.NAKACK in a broken state after
203: * DISCONNECT. Because of this problem, the channel couldn't be used to
204: * multicast messages.
205: **/
206: public void testDisconnectConnectSendTwo_TUNNEL() throws Exception {
207: try {
208: routerPort = Utilities.startGossipRouter();
209: String props = getTUNNELProps(routerPort, routerPort);
210:
211: final Promise msgPromise = new Promise();
212: JChannel coordinator = new JChannel(props);
213: coordinator.connect("testgroup");
214: PullPushAdapter ppa = new PullPushAdapter(coordinator,
215: new PromisedMessageListener(msgPromise));
216: ppa.start();
217:
218: channel = new JChannel(props);
219: channel.connect("testgroup1");
220: channel.disconnect();
221: channel.connect("testgroup");
222:
223: channel.send(new Message(null, null, "payload"));
224:
225: Message msg = (Message) msgPromise.getResult(20000);
226: assertTrue(msg != null);
227: assertEquals("payload", msg.getObject());
228:
229: ppa.stop();
230: coordinator.close();
231: } finally {
232: Utilities.stopGossipRouter();
233: }
234: }
235:
236: public static Test suite() {
237: return new TestSuite(DisconnectTest.class);
238: }
239:
240: public static void main(String[] args) {
241: String[] testCaseName = { DisconnectTest.class.getName() };
242: junit.textui.TestRunner.main(testCaseName);
243: }
244:
245: private static class PromisedMessageListener implements
246: MessageListener {
247:
248: private Promise promise;
249:
250: public PromisedMessageListener(Promise promise) {
251: this .promise = promise;
252: }
253:
254: public byte[] getState() {
255: return null;
256: }
257:
258: public void receive(Message msg) {
259: promise.setResult(msg);
260: }
261:
262: public void setState(byte[] state) {
263: }
264: }
265:
266: }
|