package org.jgroups.tests; import org.jgroups.*; import org.jgroups.util.Util; import org.testng.Assert; import org.testng.annotations.AfterMethod; import org.testng.annotations.Test; import java.util.ArrayList; import java.util.List; /** * Demos the creation of a channel and subsequent connection and closing. Demo application should exit (no * more threads running) */ @Test(groups=Global.STACK_DEPENDENT, sequential=false) public class CloseTest extends ChannelTestBase { private final ThreadLocal<JChannel> ch=new ThreadLocal<JChannel>(), channel1=new ThreadLocal<JChannel>(), c1=new ThreadLocal<JChannel>(), c2=new ThreadLocal<JChannel>(), c3=new ThreadLocal<JChannel>(); @AfterMethod void tearDown() throws Exception { closeChannel(ch); closeChannel(channel1); closeChannel(c1); closeChannel(c2); closeChannel(c3); } protected boolean useBlocking() { return false; } private static void closeChannel(ThreadLocal<JChannel> local) { Channel c=local.get(); if(c != null && (c.isOpen() || c.isConnected())) { c.close(); } local.set(null); } public void testDoubleClose() throws Exception { System.out.println("-- creating channel1 --"); channel1.set(createChannel(true)); System.out.println("-- connecting channel1 --"); channel1.get().connect(getUniqueClusterName("CloseTest.testDoubleClose")); assertTrue("channel open", channel1.get().isOpen()); assertTrue("channel connected", channel1.get().isConnected()); System.out.println("-- closing channel1 --"); channel1.get().close(); System.out.println("-- closing channel1 (again) --"); channel1.get().close(); assertFalse("channel not connected", channel1.get().isConnected()); } public void testCreationAndClose() throws Exception { System.out.println("-- creating channel1 --"); ch.set(createChannel(true)); ch.get().connect(getUniqueClusterName("CloseTest.testCreationAndClose")); assertTrue("channel open", ch.get().isOpen()); assertTrue("channel connected", ch.get().isConnected()); ch.get().close(); assertFalse("channel not connected", ch.get().isConnected()); ch.get().close(); } public void testViewChangeReceptionOnChannelCloseByParticipant() throws Exception { Address a1, a2; List<Address> members; MyReceiver r1=new MyReceiver(), r2=new MyReceiver(); c1.set(createChannel(true)); c1.get().setReceiver(r1); System.out.println("-- connecting c1"); final String GROUP="CloseTest.testViewChangeReceptionOnChannelCloseByParticipant"; c1.get().connect(GROUP); Util.sleep(500); // time to receive its own view System.out.println("c1: " + r1.getViews()); a1=c1.get().getAddress(); c2.set(createChannel(c1.get())); c2.get().setReceiver(r2); System.out.println("-- connecting c2"); r1.clearViews(); c2.get().connect(GROUP); Util.sleep(500); // time to receive its own view a2=c2.get().getAddress(); System.out.println("c2: " + r2.getViews()); System.out.println("-- closing c2"); c2.get().close(); Util.sleep(500); View v=r1.getViews().get(0); members=v.getMembers(); System.out.println("-- first view of c1: " + v); Assert.assertEquals(2, members.size()); assertTrue(members.contains(a1)); assertTrue(members.contains(a2)); v=r1.getViews().get(1); members=v.getMembers(); System.out.println("-- second view of c1: " + v); assert 1 == members.size(); assert members.contains(a1); assert !members.contains(a2); } public void testViewChangeReceptionOnChannelCloseByCoordinator() throws Exception { Address a1, a2; List<Address> members; MyReceiver r1=new MyReceiver(), r2=new MyReceiver(); final String GROUP=getUniqueClusterName("CloseTest.testViewChangeReceptionOnChannelCloseByCoordinator"); c1.set(createChannel(true)); c1.get().setReceiver(r1); c1.get().connect(GROUP); Util.sleep(500); // time to receive its own view a1=c1.get().getAddress(); c2.set(createChannel(c1.get())); c2.get().setReceiver(r2); c2.get().connect(GROUP); Util.sleep(500); // time to receive its own view a2=c2.get().getAddress(); View v=r2.getViews().get(0); members=v.getMembers(); assert 2 == members.size(); assert members.contains(a2); r2.clearViews(); c1.get().close(); Util.sleep(1000); v=r2.getViews().get(0); members=v.getMembers(); assert 1 == members.size(); assert !members.contains(a1); assert members.contains(a2); } public void testConnectDisconnectConnectCloseSequence() throws Exception { System.out.println("-- creating channel --"); ch.set(createChannel(true)); System.out.println("-- connecting channel to CloseTest--"); ch.get().connect("CloseTest.testConnectDisconnectConnectCloseSequence-CloseTest"); System.out.println("view is " + ch.get().getView()); System.out.println("-- disconnecting channel --"); ch.get().disconnect(); Util.sleep(500); System.out.println("-- connecting channel to OtherGroup --"); ch.get().connect("CloseTest.testConnectDisconnectConnectCloseSequence-OtherGroup"); System.out.println("view is " + ch.get().getView()); System.out.println("-- closing channel --"); ch.get().close(); } public void testConnectCloseSequenceWith2Members() throws Exception { System.out.println("-- creating channel --"); ch.set(createChannel(true)); System.out.println("-- connecting channel --"); final String GROUP=getUniqueClusterName("CloseTest.testConnectCloseSequenceWith2Members"); ch.get().connect(GROUP); System.out.println("view is " + ch.get().getView()); System.out.println("-- creating channel1 --"); channel1.set(createChannel(ch.get())); System.out.println("-- connecting channel1 --"); channel1.get().connect(GROUP); System.out.println("view is " + channel1.get().getView()); System.out.println("-- closing channel1 --"); channel1.get().close(); Util.sleep(2000); System.out.println("-- closing channel --"); ch.get().close(); } public void testCreationAndClose2() throws Exception { System.out.println("-- creating channel2 --"); ch.set(createChannel(true)); System.out.println("-- connecting channel2 --"); ch.get().connect(getUniqueClusterName("CloseTest.testCreationAndClose2")); System.out.println("-- closing channel --"); ch.get().close(); } public void testClosedChannel() throws Exception { System.out.println("-- creating channel --"); ch.set(createChannel(true)); System.out.println("-- connecting channel --"); ch.get().connect(getUniqueClusterName("CloseTest.testClosedChannel")); System.out.println("-- closing channel --"); ch.get().close(); Util.sleep(2000); try { ch.get().connect(getUniqueClusterName("CloseTest.testClosedChannel")); assert false; } catch(IllegalStateException ex) { assertTrue(true); } } public void testMultipleConnectsAndDisconnects() throws Exception { c1.set(createChannel(true)); assertTrue(c1.get().isOpen()); assertFalse(c1.get().isConnected()); final String GROUP=getUniqueClusterName("CloseTest.testMultipleConnectsAndDisconnects"); c1.get().connect(GROUP); System.out.println("view after c1.connect(): " + c1.get().getView()); assertTrue(c1.get().isOpen()); assertTrue(c1.get().isConnected()); assertServiceAndClusterView(c1.get(), 1); c2.set(createChannel(c1.get())); assertTrue(c2.get().isOpen()); assertFalse(c2.get().isConnected()); c2.get().connect(GROUP); System.out.println("view after c2.connect(): " + c2.get().getView()); assertTrue(c2.get().isOpen()); assertTrue(c2.get().isConnected()); assertServiceAndClusterView(c2.get(), 2); Util.sleep(500); assertServiceAndClusterView(c1.get(), 2); c2.get().disconnect(); System.out.println("view after c2.disconnect(): " + c2.get().getView()); assertTrue(c2.get().isOpen()); assertFalse(c2.get().isConnected()); Util.sleep(500); assertServiceAndClusterView(c1.get(), 1); c2.get().connect(GROUP); System.out.println("view after c2.connect(): " + c2.get().getView()); assertTrue(c2.get().isOpen()); assertTrue(c2.get().isConnected()); assertServiceAndClusterView(c2.get(), 2); Util.sleep(300); assertServiceAndClusterView(c1.get(), 2); // Now see what happens if we reconnect the first channel c3.set(createChannel(c1.get())); assertTrue(c3.get().isOpen()); assertFalse(c3.get().isConnected()); assertServiceAndClusterView(c1.get(), 2); assertServiceAndClusterView(c2.get(), 2); c1.get().disconnect(); Util.sleep(1000); assertTrue(c1.get().isOpen()); assertFalse(c1.get().isConnected()); assertServiceAndClusterView(c2.get(), 1); assertTrue(c3.get().isOpen()); assertFalse(c3.get().isConnected()); c1.get().connect(GROUP); System.out.println("view after c1.connect(): " + c1.get().getView()); assertTrue(c1.get().isOpen()); assertTrue(c1.get().isConnected()); assertServiceAndClusterView(c1.get(), 2); Util.sleep(500); assertServiceAndClusterView(c2.get(), 2); assertTrue(c3.get().isOpen()); assertFalse(c3.get().isConnected()); } private static void assertServiceAndClusterView(Channel ch, int num) { View view=ch.getView(); String msg="view=" + view; assertNotNull(view); Assert.assertEquals(view.size(), num, msg); } private static class MyReceiver extends ReceiverAdapter { final List<View> views=new ArrayList<View>(); public void viewAccepted(View new_view) { views.add(new_view); System.out.println("new_view = " + new_view); } public List<View> getViews() {return views;} public void clearViews() {views.clear();} } }