package org.jgroups.tests; import org.jgroups.Global; import org.jgroups.JChannel; import org.jgroups.Message; import org.jgroups.ReceiverAdapter; import org.jgroups.protocols.FRAG2; import org.jgroups.protocols.MPING; import org.jgroups.protocols.TCP_NIO2; import org.jgroups.protocols.UNICAST3; import org.jgroups.protocols.pbcast.GMS; import org.jgroups.protocols.pbcast.NAKACK2; import org.jgroups.protocols.pbcast.STABLE; import org.jgroups.stack.Protocol; import org.jgroups.util.Util; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import java.util.ArrayList; import java.util.List; /** * Tests sending of multicast messages via TCP_NIO2 from A to {A,B} * @author Bela Ban * @since 3.6.7 */ @Test(groups=Global.FUNCTIONAL,singleThreaded=true) public class NioServerTest2 { protected static final int NUM_MSGS=10000; protected static final int MSG_SIZE=1000; protected static final int recv_buf_size=50000, send_buf_size=10000; protected JChannel a, b; protected MyReceiver ra, rb; @BeforeMethod protected void init() throws Exception { a=create("A"); a.setReceiver(ra=new MyReceiver()); b=create("B"); b.setReceiver(rb=new MyReceiver()); a.connect("NioServerTest2"); b.connect("NioServerTest2"); Util.waitUntilAllChannelsHaveSameView(10000, 500, a, b); } @AfterMethod protected void destroy() {Util.close(b,a);} public void testMulticasting() throws Exception { for(int i=1; i<= NUM_MSGS; i++) { Message msg=new Message(null, new byte[MSG_SIZE], 0, MSG_SIZE); a.send(msg); } for(int i=0; i < 20; i++) { if(ra.total() >= NUM_MSGS && rb.total() >= NUM_MSGS) break; System.out.printf("A.good=%d | bad=%d, B.good=%d | bad=%d\n", ra.good(), ra.bad(), rb.good(), rb.bad()); Util.sleep(500); } TCP_NIO2 ta=(TCP_NIO2)a.getProtocolStack().getTransport(), tb=(TCP_NIO2)b.getProtocolStack().getTransport(); System.out.printf("A.partial_writes=%d, B.partial_writes=%d\n", ta.numPartialWrites(), tb.numPartialWrites()); NAKACK2 na=(NAKACK2)a.getProtocolStack().findProtocol(NAKACK2.class), nb=(NAKACK2)b.getProtocolStack().findProtocol(NAKACK2.class); System.out.printf("A.xmit_reqs_sent|received=%d|%d, B.xmit_reqs_sent|received=%d|%d\n", na.getXmitRequestsSent(), na.getXmitRequestsReceived(), nb.getXmitRequestsSent(), nb.getXmitRequestsReceived()); System.out.printf("A.good=%d | bad=%d, B.good=%d | bad=%d\n", ra.good(), ra.bad(), rb.good(), rb.bad()); check(ra, "A"); check(rb, "B"); } protected void check(MyReceiver r, String name) { if(r.bad() > 0) { List<byte[]> bad_msgs=r.badMsgs(); for(byte[] arr: bad_msgs) System.out.printf("bad buffer for %s: length=%d\n", name, arr.length); assert r.bad() == 0 : String.format("%s.good=%d | bad=%d\n", name, r.good(), r.bad()); } assert r.total() == NUM_MSGS : String.format("%s.good=%d | bad=%d\n", name, r.good(), r.bad()); } protected static JChannel create(String name) throws Exception { return new JChannel(new Protocol[] { new TCP_NIO2() .setValue("bind_addr", Util.getLocalhost()) .setValue("recv_buf_size", recv_buf_size).setValue("send_buf_size", send_buf_size), new MPING(), new NAKACK2().setValue("use_mcast_xmit", false), new UNICAST3(), new STABLE(), new GMS().joinTimeout(1000), new FRAG2() } ).name(name); // JChannel ch=new JChannel("/home/bela/bad-tcp-nio.xml").name(name); //TCP_NIO2 tp=(TCP_NIO2)ch.getProtocolStack().getTransport(); //tp.setValue("recv_buf_size", recv_buf_size).setValue("send_buf_size", send_buf_size); //return ch; } protected static class MyReceiver extends ReceiverAdapter { protected int good, bad; protected List<byte[]> bad_msgs=new ArrayList<>(1000); public int good() {return good;} public int bad() {return bad;} public int total() {return good+bad;} public List<byte[]> badMsgs() {return bad_msgs;} public void receive(Message msg) { if(msg.getLength() != MSG_SIZE) { bad++; byte[] copy=new byte[msg.getLength()]; byte[] buf=null; buf=msg.getRawBuffer(); System.arraycopy(buf, msg.getOffset(), copy, 0, copy.length); bad_msgs.add(copy); } else good++; } } }