package org.jgroups.tests; import org.jgroups.Global; import org.jgroups.JChannel; import org.jgroups.View; import org.jgroups.protocols.*; import org.jgroups.protocols.pbcast.GMS; import org.jgroups.protocols.pbcast.NAKACK2; import org.jgroups.protocols.pbcast.STABLE; import org.jgroups.util.Util; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import java.util.concurrent.CyclicBarrier; /** * Creates 1 channel, then creates NUM channels, all try to join the same channel concurrently. * @author Bela Ban Nov 20 2003 */ @Test(groups=Global.FUNCTIONAL,singleThreaded=true) public class ConnectStressTest { protected static final int NUM=20; protected final CyclicBarrier barrier=new CyclicBarrier(NUM+1); protected final JChannel[] channels=new JChannel[NUM]; protected final MyThread[] threads=new MyThread[NUM]; static void log(String msg) { System.out.println("-- [" + Thread.currentThread().getName() + "] " + msg); } @BeforeMethod protected void setup() throws Exception { for(int i=0; i < NUM; i++) { channels[i]=createChannel(String.valueOf((char)(i + 1))); if(i == 0) channels[i].connect("ConnectStressTest"); } } @AfterMethod protected void destroy() {Util.close(channels);} public void testConcurrentJoining() throws Exception { for(int i=0; i < NUM; i++) { threads[i]=new MyThread(channels[i], i+1, barrier); threads[i].start(); } barrier.await(); // causes all threads to call Channel.connect() System.out.println("*** Starting the connect phase ***"); long target_time=System.currentTimeMillis() + 60000L; while(System.currentTimeMillis() < target_time) { View view=channels[0].getView(); if(view != null) { int size=view.size(); System.out.println("channel[0].view has " + size + " members (expected: " + NUM + ")"); if(size >= NUM) break; } Util.sleep(1000L); } for(JChannel ch: channels) { View view=ch.getView(); if(view != null) System.out.println(ch.getName() + ": size=" + view.size() + ", view-id: " + view.getViewId()); } for(JChannel ch: channels) { View view=ch.getView(); int size=view != null? view.size() : 0; assert view != null && size == NUM : "view doesn't have size of " + NUM + " (has " + size + "): " + view; } } public static class MyThread extends Thread { private final CyclicBarrier barrier; private final JChannel ch; public MyThread(JChannel channel, int i, CyclicBarrier barrier) { super("thread #" + i); this.ch=channel; this.barrier=barrier; } public void run() { try { barrier.await(); // wait for all threads to be running ch.connect("ConnectStressTest"); } catch(Exception e) { } } } protected JChannel createChannel(String name) throws Exception { return new JChannel(new SHARED_LOOPBACK(), new SHARED_LOOPBACK_PING(), new MERGE3().setValue("min_interval", 2000).setValue("max_interval", 5000), new NAKACK2().setValue("log_discard_msgs", false), new UNICAST3(), new STABLE(), new GMS().joinTimeout(1000).setValue("view_bundling", true).setValue("max_bundling_time", 300) .setValue("print_local_addr", false), new FRAG2().fragSize(8000)); } }