package org.jgroups.tests; import org.jgroups.*; 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.stack.Protocol; import org.jgroups.util.Util; import org.testng.annotations.AfterMethod; import org.testng.annotations.Test; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; /** * Tests unicast functionality * @author Bela Ban */ @Test(groups=Global.FUNCTIONAL,singleThreaded=true) public class UnicastUnitTest { protected JChannel a, b; @AfterMethod protected void tearDown() throws Exception {Util.close(b, a);} public void testUnicastMessageInCallbackExistingMember() throws Throwable { a=create("A", false); b=create("B", false); a.connect("UnicastUnitTest"); MyReceiver receiver=new MyReceiver(a); a.setReceiver(receiver); b.connect("UnicastUnitTest"); a.setReceiver(null); // so the receiver doesn't get a view change Throwable ex=receiver.getEx(); if(ex != null) throw ex; } /** Tests sending msgs from A to B */ // @Test(invocationCount=10) public void testMessagesToOther() throws Exception { a=create("A", false); b=create("B", false); _testMessagesToOther(); } public void testMessagesToOtherBatching() throws Exception { a=create("A", true); b=create("B", true); _testMessagesToOther(); } protected void _testMessagesToOther() throws Exception { connect(); Address dest=b.getAddress(); Message[] msgs={ msg(dest), // reg msg(dest), msg(dest).setFlag(Message.Flag.OOB), msg(dest).setTransientFlag(Message.TransientFlag.DONT_LOOPBACK), msg(dest) }; MyReceiver receiver=new MyReceiver(); b.setReceiver(receiver); send(a, msgs); checkReception(receiver, false, 1,2,3,4,5); } // @Test(invocationCount=10) public void testMessagesToSelf() throws Exception { a=create("A", false); b=create("B", false); _testMessagesToSelf(); } public void testMessagesToSelfBatching() throws Exception { a=create("A", true); b=create("B", true); _testMessagesToSelf(); } protected void _testMessagesToSelf() throws Exception { connect(); Address dest=a.getAddress(); Message[] msgs={ msg(dest), msg(dest), msg(dest).setFlag(Message.Flag.OOB, Message.Flag.INTERNAL), msg(dest).setTransientFlag(Message.TransientFlag.DONT_LOOPBACK), msg(dest), msg(dest).setTransientFlag(Message.TransientFlag.DONT_LOOPBACK), msg(dest).setTransientFlag(Message.TransientFlag.DONT_LOOPBACK), msg(dest), msg(dest) }; MyReceiver receiver=new MyReceiver(); a.setReceiver(receiver); send(a, msgs); checkReception(receiver, false, 1,2,3,5,8,9); } public void testMessagesToSelf2() throws Exception { a=create("A", false); b=create("B", false); _testMessagesToSelf2(); } public void testMessagesToSelf2Batching() throws Exception { a=create("A", true); b=create("B", true); _testMessagesToSelf2(); } protected void _testMessagesToSelf2() throws Exception { connect(); Address dest=a.getAddress(); Message[] msgs={ msg(dest).setFlag(Message.Flag.OOB).setTransientFlag(Message.TransientFlag.DONT_LOOPBACK), msg(dest).setFlag(Message.Flag.OOB), msg(dest).setFlag(Message.Flag.OOB).setTransientFlag(Message.TransientFlag.DONT_LOOPBACK), msg(dest).setFlag(Message.Flag.OOB).setTransientFlag(Message.TransientFlag.DONT_LOOPBACK), msg(dest).setFlag(Message.Flag.OOB), msg(dest).setFlag(Message.Flag.OOB), msg(dest).setFlag(Message.Flag.OOB).setTransientFlag(Message.TransientFlag.DONT_LOOPBACK), msg(dest).setFlag(Message.Flag.OOB).setTransientFlag(Message.TransientFlag.DONT_LOOPBACK), msg(dest).setFlag(Message.Flag.OOB).setTransientFlag(Message.TransientFlag.DONT_LOOPBACK), msg(dest), msg(dest).setFlag(Message.Flag.OOB).setTransientFlag(Message.TransientFlag.DONT_LOOPBACK), }; MyReceiver receiver=new MyReceiver(); a.setReceiver(receiver); send(a, msgs); checkReception(receiver, false, 2,5,6,10); } protected void send(JChannel ch, Message ... msgs) throws Exception { int cnt=1; for(Message msg: msgs) { assert msg.dest() != null; msg.setObject(cnt++); ch.send(msg); } } protected void checkReception(MyReceiver r, boolean check_order, int ... num) { List<Integer> received=r.list(); for(int i=0; i < 10; i++) { if(received.size() == num.length) break; Util.sleep(500); } List<Integer> expected=new ArrayList<>(num.length); for(int n: num) expected.add(n); System.out.println("received=" + received + ", expected=" + expected); assert received.size() == expected.size() : "list=" + received + ", expected=" + expected; assert received.containsAll(expected) : "list=" + received + ", expected=" + expected; if(check_order) for(int i=0; i < num.length; i++) assert num[i] == received.get(i); } protected Message msg(Address dest) {return new Message(dest);} protected JChannel create(String name, boolean use_batching) throws Exception { Protocol[] protocols={ new SHARED_LOOPBACK(), new SHARED_LOOPBACK_PING(), new NAKACK2(), new MAKE_BATCH().sleepTime(100).unicasts(use_batching), new UNICAST3(), new STABLE(), new GMS(), new FRAG2().fragSize(8000), }; return new JChannel(protocols).name(name); } protected void connect() throws Exception { a.connect("UnicastUnitTest"); b.connect("UnicastUnitTest"); Util.waitUntilAllChannelsHaveSameView(10000, 1000, a, b); } protected static class MyReceiver extends ReceiverAdapter { protected JChannel channel; protected Throwable ex; protected final List<Integer> list=new ArrayList<>(); public MyReceiver() {this(null);} public MyReceiver(JChannel ch) {this.channel=ch;} public Throwable getEx() {return ex;} public List<Integer> list() {return list;} public void clear() {list.clear();} public void receive(Message msg) { Integer num=(Integer)msg.getObject(); synchronized(list) { list.add(num); } // System.out.println("<-- " + num); } public void viewAccepted(View new_view) { if(channel == null) return; Address local_addr=channel.getAddress(); assert local_addr != null; System.out.println("[" + local_addr + "]: " + new_view); List<Address> members=new LinkedList<>(new_view.getMembers()); assert 2 == members.size() : "members=" + members + ", local_addr=" + local_addr + ", view=" + new_view; Address dest=members.get(0); Message unicast_msg=new Message(dest); try { channel.send(unicast_msg); } catch(Throwable e) { ex=e; throw new RuntimeException(e); } } } }