protected void waitForBridgeView( int expected_size, long timeout, long interval, JChannel... channels) { long deadline = System.currentTimeMillis() + timeout; while (System.currentTimeMillis() < deadline) { boolean views_correct = true; for (JChannel ch : channels) { RELAY2 relay = (RELAY2) ch.getProtocolStack().findProtocol(RELAY2.class); View bridge_view = relay.getBridgeView(BRIDGE_CLUSTER); if (bridge_view == null || bridge_view.size() != expected_size) { views_correct = false; break; } } if (views_correct) break; Util.sleep(interval); } System.out.println("Bridge views:\n"); for (JChannel ch : channels) { RELAY2 relay = (RELAY2) ch.getProtocolStack().findProtocol(RELAY2.class); View bridge_view = relay.getBridgeView(BRIDGE_CLUSTER); System.out.println(ch.getAddress() + ": " + bridge_view); } for (JChannel ch : channels) { RELAY2 relay = (RELAY2) ch.getProtocolStack().findProtocol(RELAY2.class); View bridge_view = relay.getBridgeView(BRIDGE_CLUSTER); assert bridge_view != null && bridge_view.size() == expected_size : ch.getAddress() + ": bridge view=" + bridge_view + ", expected=" + expected_size; } }
public void testRegularUnicastsToOthers() throws Exception { send(c1, c2.getAddress(), false, 10); send(c1, c3.getAddress(), false, 10); sendStableMessages(c1, c2, c3); check(r2, 1, false, new Tuple<Address, Integer>(a1, 10)); check(r3, 1, false, new Tuple<Address, Integer>(a1, 10)); }
/** Creates a singleton view for each channel listed and injects it */ protected static void createPartition(JChannel... channels) { for (JChannel ch : channels) { View view = Util.createView(ch.getAddress(), 5, ch.getAddress()); GMS gms = (GMS) ch.getProtocolStack().findProtocol(GMS.class); gms.installView(view); } }
private void sendMessageToBothChannels(int size) throws Exception { long start, stop; d1.setRequestHandler(new MyHandler(new byte[size])); c2 = createChannel(c1); c2.setName("B"); disableBundling(c2); d2 = new MessageDispatcher(c2, null, null, new MyHandler(new byte[size])); c2.connect("MessageDispatcherUnitTest"); Assert.assertEquals(2, c2.getView().size()); System.out.println("casting message"); start = System.currentTimeMillis(); RspList rsps = d1.castMessage(null, new Message(), new RequestOptions(ResponseMode.GET_ALL, 0)); stop = System.currentTimeMillis(); System.out.println("rsps:\n" + rsps); System.out.println("call took " + (stop - start) + " ms"); assertNotNull(rsps); Assert.assertEquals(2, rsps.size()); Rsp rsp = rsps.get(c1.getAddress()); assertNotNull(rsp); byte[] ret = (byte[]) rsp.getValue(); Assert.assertEquals(size, ret.length); rsp = rsps.get(c2.getAddress()); assertNotNull(rsp); ret = (byte[]) rsp.getValue(); Assert.assertEquals(size, ret.length); Util.close(c2); }
public void testNullMessageToAll() throws Exception { d1.setRequestHandler(new MyHandler(null)); c2 = createChannel(c1); c2.setName("B"); disableBundling(c2); long stop, start = System.currentTimeMillis(); d2 = new MessageDispatcher(c2, null, null, new MyHandler(null)); stop = System.currentTimeMillis(); c2.connect("MessageDispatcherUnitTest"); Assert.assertEquals(2, c2.getView().size()); System.out.println("view: " + c2.getView()); System.out.println("casting message"); start = System.currentTimeMillis(); RspList rsps = d1.castMessage(null, new Message(), new RequestOptions(ResponseMode.GET_ALL, 0)); stop = System.currentTimeMillis(); System.out.println("rsps:\n" + rsps); System.out.println("call took " + (stop - start) + " ms"); assertNotNull(rsps); Assert.assertEquals(2, rsps.size()); Rsp rsp = rsps.get(c1.getAddress()); assertNotNull(rsp); Object ret = rsp.getValue(); assert ret == null; rsp = rsps.get(c2.getAddress()); assertNotNull(rsp); ret = rsp.getValue(); assert ret == null; Util.close(c2); }
@Test(invocationCount = 10) public void testOOBUnicastsToOthers() throws Exception { send(c1, c2.getAddress(), true, 10); send(c1, c3.getAddress(), true, 10); sendStableMessages(c1, c2, c3); check(r2, 1, true, new Tuple<Address, Integer>(a1, 10)); check(r3, 1, true, new Tuple<Address, Integer>(a1, 10)); }
/** * Multiple threads (NUM_THREADS) send messages (NUM_MSGS) * * @throws Exception */ @Test(dataProvider = "provider") public void testMessageReceptionUnderHighLoad(String props) throws Exception { CountDownLatch latch = new CountDownLatch(1); c1 = new JChannel(props); c2 = new JChannel(props); MyReceiver r1 = new MyReceiver("c1"), r2 = new MyReceiver("c2"); c1.setReceiver(r1); c2.setReceiver(r2); c1.connect("testSimpleMessageReception"); c2.connect("testSimpleMessageReception"); Address c1_addr = c1.getAddress(), c2_addr = c2.getAddress(); MySender[] c1_senders = new MySender[NUM_THREADS]; for (int i = 0; i < c1_senders.length; i++) { c1_senders[i] = new MySender(c1, c2_addr, latch); c1_senders[i].start(); } MySender[] c2_senders = new MySender[NUM_THREADS]; for (int i = 0; i < c2_senders.length; i++) { c2_senders[i] = new MySender(c2, c1_addr, latch); c2_senders[i].start(); } Util.sleep(500); latch.countDown(); // starts all threads long NUM_EXPECTED_MSGS = NUM_THREADS * NUM_MSGS; for (int i = 0; i < 20; i++) { if (r1.getNum() == NUM_EXPECTED_MSGS && r2.getNum() == NUM_EXPECTED_MSGS) break; Util.sleep(2000); UNICAST2 unicast2 = (UNICAST2) c1.getProtocolStack().findProtocol(UNICAST2.class); if (unicast2 != null) unicast2.sendStableMessages(); unicast2 = (UNICAST2) c2.getProtocolStack().findProtocol(UNICAST2.class); if (unicast2 != null) unicast2.sendStableMessages(); } System.out.println( "c1 received " + r1.getNum() + " msgs, " + getNumberOfRetransmissions(c1) + " retransmissions"); System.out.println( "c2 received " + r2.getNum() + " msgs, " + getNumberOfRetransmissions(c2) + " retransmissions"); assert r1.getNum() == NUM_EXPECTED_MSGS : "expected " + NUM_EXPECTED_MSGS + ", but got " + r1.getNum(); assert r2.getNum() == NUM_EXPECTED_MSGS : "expected " + NUM_EXPECTED_MSGS + ", but got " + r2.getNum(); }
/** * Verifies that unicasts are received correctly by all participants after an overlapping merge. * The following steps are executed: * * <ol> * <li/>Group is {A,B,C}, A is the coordinator * <li/>MERGE2 is removed from all members * <li/>VERIFY_SUSPECT is removed from all members * <li/>Everyone sends 5 unicast messages to everyone else * <li/>A VIEW(B,C) is injected into B and C * <li/>B and C install {B,C} * <li/>B and C trash the connection table for A in UNICAST * <li/>A still has view {A,B,C} and all connection tables intact in UNICAST * <li/>We now send N unicasts from everyone to everyone else, all the unicasts should be * received. * </ol> */ public void testWithViewBC() throws Exception { System.out.println("A's view: " + a.getView()); // Inject view {B,C} into B and C: View new_view = Util.createView(b.getAddress(), 10, b.getAddress(), c.getAddress()); injectView(new_view, b, c); assertEquals("A's view is " + a.getView(), 3, a.getView().size()); assertEquals("B's view is " + b.getView(), 2, b.getView().size()); assertEquals("C's view is " + c.getView(), 2, c.getView().size()); sendAndCheckMessages(5, a, b, c); }
private static void createPartitions(JChannel... channels) throws Exception { for (JChannel ch : channels) { DISCARD discard = new DISCARD(); discard.setDiscardAll(true); ch.getProtocolStack().insertProtocol(discard, ProtocolStack.Position.ABOVE, TP.class); } for (JChannel ch : channels) { View view = View.create(ch.getAddress(), 10, ch.getAddress()); GMS gms = (GMS) ch.getProtocolStack().findProtocol(GMS.class); gms.installView(view); } }
/** * Set Frame's title * * @param title : frame's title */ void setTitle(String title) { String tmp = ""; if (noChannel) { mainFrame.setTitle("JWhiteBoard"); return; } if (title != null) { mainFrame.setTitle(title); } else { if (channel.getAddress() != null) tmp += channel.getAddress(); tmp += " (" + memberSize + ")"; mainFrame.setTitle(tmp); } }
@Test public void testJoinMessageReceivedForDisconnectedHost() throws Exception { final AtomicInteger counter1 = new AtomicInteger(0); final AtomicInteger counter2 = new AtomicInteger(0); connector1.subscribe(String.class.getName(), new CountingCommandHandler(counter1)); connector1.connect(20); assertTrue( "Expected connector 1 to connect within 10 seconds", connector1.awaitJoined(10, TimeUnit.SECONDS)); connector2.subscribe(String.class.getName(), new CountingCommandHandler(counter2)); connector2.connect(80); assertTrue("Connector 2 failed to connect", connector2.awaitJoined()); // wait for both connectors to have the same view waitForConnectorSync(); ConsistentHash hashBefore = connector1.getConsistentHash(); // secretly insert an illegal message channel1 .getReceiver() .receive( new Message( channel1.getAddress(), new IpAddress(12345), new JoinMessage(10, Collections.<String>emptySet()))); ConsistentHash hash2After = connector1.getConsistentHash(); assertEquals("That message should not have changed the ring", hashBefore, hash2After); }
/** Execute when new member join or leave Group */ public void viewAccepted(View v) { memberSize = v.size(); if (mainFrame != null) setTitle(); members.clear(); members.addAll(v.getMembers()); if (v instanceof MergeView) { System.out.println("** " + v); // This is a simple merge function, which fetches the state from the coordinator // on a merge and overwrites all of its own state if (useState && !members.isEmpty()) { Address coord = members.get(0); Address local_addr = channel.getAddress(); if (local_addr != null && !local_addr.equals(coord)) { try { // make a copy of our state first Map<Point, Color> copy = null; if (send_own_state_on_merge) { synchronized (drawPanel.state) { copy = new LinkedHashMap<Point, Color>(drawPanel.state); } } System.out.println("fetching state from " + coord); channel.getState(coord, 5000); if (copy != null) sendOwnState(copy); // multicast my own state so everybody else has it too } catch (Exception e) { e.printStackTrace(); } } } } else System.out.println("** View=" + v); }
/** When receive a message, analyze message content and then execute the command: Draw or Clear */ public void receive(Message msg) { byte[] buf = msg.getRawBuffer(); if (buf == null) { System.err.println( "[" + channel.getAddress() + "] received null buffer from " + msg.getSrc() + ", headers: " + msg.printHeaders()); return; } try { DrawCommand comm = (DrawCommand) Util.streamableFromByteBuffer( DrawCommand.class, buf, msg.getOffset(), msg.getLength()); switch (comm.mode) { case DrawCommand.DRAW: if (drawPanel != null) drawPanel.drawPoint(comm); break; case DrawCommand.CLEAR: clearPanel(); default: System.err.println("***** received invalid draw command " + comm.mode); break; } } catch (Exception e) { e.printStackTrace(); } }
private boolean viewContains(View view, JChannel... channels) { boolean b = true; for (JChannel ch : channels) { b = b && view.containsMember(ch.getAddress()); } return b; }
private static void mergePartitions(JChannel... channels) throws Exception { Membership membership = new Membership(); for (JChannel ch : channels) { membership.add(ch.getAddress()); } membership.sort(); Address leaderAddress = membership.elementAt(0); JChannel leader = findChannelByAddress(leaderAddress, channels); GMS gms = (GMS) leader.getProtocolStack().findProtocol(GMS.class); gms.setLevel("trace"); Map<Address, View> views = new HashMap<>(); for (JChannel ch : channels) { views.put(ch.getAddress(), ch.getView()); } gms.up(new Event(Event.MERGE, views)); }
/** * If the coordinator of the lock locks the lock and then send a message, the receiver will wait * for ever in tryLock. However, castMessage will return after a while because of the default * settings of RequestOptions.SYNC(). */ public void testCoordSendFirst() throws Exception { System.out.println("Running testCoordSendFirst"); // =========================================================================== if (lock_a.tryLock()) { try { System.out.println("A aquired the lock, about to send message to B"); String rsp = disp_a.sendMessage( new Message(b.getAddress(), "bla"), RequestOptions.SYNC().setTimeout(60000)); if (rsp == null) { System.err.println("ERROR: didn't return correctly"); Assert.fail("Didn't return correctly"); } else System.out.println("Returned: " + rsp); } finally { lock_a.unlock(); } } else { Assert.fail("The lock was already locked"); System.out.println("A failed to aquire the lock"); } // =========================================================================== System.out.println(); }
/** Tests https://jira.jboss.org/jira/browse/JGRP-1079 for unicast messages */ public void testOOBUnicastMessageLoss() throws Exception { MyReceiver receiver = new MySleepingReceiver("C2", 1000); b.setReceiver(receiver); a.getProtocolStack().getTransport().setOOBRejectionPolicy("discard"); final int NUM = 10; final Address dest = b.getAddress(); for (int i = 1; i <= NUM; i++) { Message msg = new Message(dest, null, i); msg.setFlag(Message.OOB); a.send(msg); } Collection<Integer> msgs = receiver.getMsgs(); for (int i = 0; i < 20; i++) { if (msgs.size() == NUM) break; Util.sleep(1000); // sendStableMessages(c1,c2); // not needed for unicasts ! } assert msgs.size() == NUM : "expected " + NUM + " messages but got " + msgs.size() + ", msgs=" + Util.print(msgs); for (int i = 1; i <= NUM; i++) { assert msgs.contains(i); } }
/** * Tests sending 1, 2 (OOB) and 3, where they are received in the order 1, 3, 2. Message 3 should * not get delivered until message 4 is received (http://jira.jboss.com/jira/browse/JGRP-780) */ public void testRegularAndOOBUnicasts() throws Exception { DISCARD discard = new DISCARD(); ProtocolStack stack = a.getProtocolStack(); stack.insertProtocol(discard, ProtocolStack.BELOW, UNICAST.class, UNICAST2.class); Address dest = b.getAddress(); Message m1 = new Message(dest, null, 1); Message m2 = new Message(dest, null, 2); m2.setFlag(Message.OOB); Message m3 = new Message(dest, null, 3); MyReceiver receiver = new MyReceiver("C2"); b.setReceiver(receiver); a.send(m1); discard.setDropDownUnicasts(1); a.send(m2); a.send(m3); Collection<Integer> list = receiver.getMsgs(); int count = 10; while (list.size() < 3 && --count > 0) { Util.sleep(500); // time for potential retransmission sendStableMessages(a, b); } assert list.size() == 3 : "list is " + list; assert list.contains(1) && list.contains(2) && list.contains(3); }
public void testRegularAndOOBUnicasts2() throws Exception { DISCARD discard = new DISCARD(); ProtocolStack stack = a.getProtocolStack(); stack.insertProtocol( discard, ProtocolStack.BELOW, (Class<? extends Protocol>[]) Util.getUnicastProtocols()); Address dest = b.getAddress(); Message m1 = new Message(dest, 1); Message m2 = new Message(dest, 2).setFlag(Message.Flag.OOB); Message m3 = new Message(dest, 3).setFlag(Message.Flag.OOB); Message m4 = new Message(dest, 4); MyReceiver receiver = new MyReceiver("B"); b.setReceiver(receiver); a.send(m1); discard.setDropDownUnicasts(2); a.send(m2); // dropped a.send(m3); // dropped a.send(m4); Collection<Integer> list = receiver.getMsgs(); int count = 10; while (list.size() < 4 && --count > 0) { Util.sleep(500); // time for potential retransmission sendStableMessages(a, b); } System.out.println("list = " + list); assert list.size() == 4 : "list is " + list; assert list.contains(1) && list.contains(2) && list.contains(3) && list.contains(4); }
private static JChannel findChannelByAddress(Address address, JChannel... channels) { for (JChannel ch : channels) { if (ch.getAddress().equals(address)) { return ch; } } return null; }
@BeforeMethod void init() throws Exception { createChannels(true, true, (short) 5, (short) 5); c1.setName("C1"); c2.setName("C2"); c3.setName("C3"); a1 = c1.getAddress(); a2 = c2.getAddress(); a3 = c3.getAddress(); r1 = new MyReceiver("C1"); r2 = new MyReceiver("C2"); r3 = new MyReceiver("C3"); c1.setReceiver(r1); c2.setReceiver(r2); c3.setReceiver(r3); }
@BeforeMethod void start() throws Exception { r1 = new MyReceiver("A"); r2 = new MyReceiver("B"); a = new JChannel(props); a.setName("A"); a.connect(CLUSTER); a_addr = a.getAddress(); a.setReceiver(r1); u1 = a.getProtocolStack().findProtocol(UNICAST.class); b = new JChannel(props); b.setName("B"); b.connect(CLUSTER); b_addr = b.getAddress(); b.setReceiver(r2); u2 = b.getProtocolStack().findProtocol(UNICAST.class); System.out.println("A=" + a_addr + ", B=" + b_addr); }
protected void receive(Message msg) { String greeting = (String) msg.getObject(); msgs.add(greeting); System.out.println("received " + greeting + " from " + msg.getSrc()); if (HELLO1.equals(greeting)) { try { a.send(new Message(a.getAddress(), HELLO2)); } catch (Exception e) { ex = e; } } }
private void sendAndCheckMessages(int num_msgs, JChannel... channels) throws Exception { ra.clear(); rb.clear(); rc.clear(); // 1. send unicast messages Set<Address> mbrs = new HashSet<Address>(channels.length); for (JChannel ch : channels) mbrs.add(ch.getAddress()); for (JChannel ch : channels) { Address addr = ch.getAddress(); for (Address dest : mbrs) { for (int i = 1; i <= num_msgs; i++) { ch.send(dest, null, "unicast msg #" + i + " from " + addr); } } } int total_msgs = num_msgs * channels.length; MyReceiver[] receivers = new MyReceiver[channels.length]; for (int i = 0; i < channels.length; i++) receivers[i] = (MyReceiver) channels[i].getReceiver(); checkReceivedMessages(total_msgs, receivers); }
/** * Tests a simple split: {A,B} and {C,D} need to merge back into one subgroup. Checks how many * MergeViews are installed */ public void testSplitInTheMiddle2() throws Exception { View v1 = View.create(a.getAddress(), 10, a.getAddress(), b.getAddress()); View v2 = View.create(c.getAddress(), 10, c.getAddress(), d.getAddress()); injectView(v1, a, b); injectView(v2, c, d); enableInfoSender(false, a, b, c, d); Util.waitUntilAllChannelsHaveSameSize(10000, 500, a, b); Util.waitUntilAllChannelsHaveSameSize(10000, 500, c, d); enableInfoSender(false, a, b, c, d); for (JChannel ch : Arrays.asList(a, b, c, d)) System.out.println(ch.getName() + ": " + ch.getView()); System.out.println("\nEnabling INFO sending in merge protocols to merge subclusters"); enableInfoSender(true, a, b, c, d); Util.waitUntilAllChannelsHaveSameSize(30000, 1000, a, b, c, d); System.out.println("\nResulting views:"); for (JChannel ch : Arrays.asList(a, b, c, d)) { GMS gms = (GMS) ch.getProtocolStack().findProtocol(GMS.class); View mv = gms.view(); System.out.println(mv); } for (JChannel ch : Arrays.asList(a, b, c, d)) { GMS gms = (GMS) ch.getProtocolStack().findProtocol(GMS.class); View mv = gms.view(); assert mv instanceof MergeView; assert mv.size() == 4; assert ((MergeView) mv).getSubgroups().size() == 2; } for (JChannel ch : Arrays.asList(a, b, c, d)) { View view = ch.getView(); assert view.size() == 4 : "view should have 4 members: " + view; } }
@Test(dataProvider = "provider") public void testSimpleMessageReception(String props) throws Exception { c1 = new JChannel(props); c2 = new JChannel(props); MyReceiver r1 = new MyReceiver("c1"), r2 = new MyReceiver("c2"); c1.setReceiver(r1); c2.setReceiver(r2); c1.connect("testSimpleMessageReception"); c2.connect("testSimpleMessageReception"); int NUM = 100; Address c1_addr = c1.getAddress(), c2_addr = c2.getAddress(); for (int i = 1; i <= NUM; i++) { c1.send(c1_addr, "bla"); c1.send(c2_addr, "bla"); c2.send(c2_addr, "bla"); c2.send(c1_addr, "bla"); } for (int i = 0; i < 10; i++) { if (r1.getNum() == NUM * 2 && r2.getNum() == NUM * 2) break; Util.sleep(500); } System.out.println( "c1 received " + r1.getNum() + " msgs, " + getNumberOfRetransmissions(c1) + " retransmissions"); System.out.println( "c2 received " + r2.getNum() + " msgs, " + getNumberOfRetransmissions(c2) + " retransmissions"); assert r1.getNum() == NUM * 2 : "expected " + NUM * 2 + ", but got " + r1.getNum(); assert r2.getNum() == NUM * 2 : "expected " + NUM * 2 + ", but got " + r2.getNum(); }
public void testWithEveryoneHavingASingletonView() throws Exception { // Inject view {A} into A, B and C: injectView(Util.createView(a.getAddress(), 10, a.getAddress()), a); injectView(Util.createView(b.getAddress(), 10, b.getAddress()), b); injectView(Util.createView(c.getAddress(), 10, c.getAddress()), c); sendAndCheckMessages(5, a, b, c); }
public void connect() { try { channel.connect("TOTAL_TOKEN_DEMO_GROUP"); } catch (ChannelException e) { e.printStackTrace(); } receiverThread = new ReceiverThread(); receiverThread.start(); Address a = channel.getAddress(); if (a != null) setTitle(a.toString()); else setTitle("Not connected"); control.connected(); }
/** * Tests a simple split: {A,B} and {C,D} need to merge back into one subgroup. Checks how many * MergeViews are installed */ public void testSplitInTheMiddle() { View v1 = View.create(a.getAddress(), 10, a.getAddress(), b.getAddress()); View v2 = View.create(c.getAddress(), 10, c.getAddress(), d.getAddress()); injectView(v1, a, b); injectView(v2, c, d); Util.waitUntilAllChannelsHaveSameSize(10000, 500, a, b); Util.waitUntilAllChannelsHaveSameSize(10000, 500, c, d); for (JChannel ch : Arrays.asList(a, b, c, d)) System.out.println(ch.getName() + ": " + ch.getView()); Address merge_leader_one = new Membership().add(a.getAddress(), b.getAddress()).sort().elementAt(0); Address merge_leader_two = new Membership().add(c.getAddress(), d.getAddress()).sort().elementAt(0); for (int x = 0; x < 20; x++) { if (a.getView().size() == 4 && b.getView().size() == 4 && c.getView().size() == 4 && d.getView().size() == 4) break; for (JChannel ch : Arrays.asList(a, b, c, d)) { MERGE3 merge = (MERGE3) ch.getProtocolStack().findProtocol(MERGE3.class); merge.sendInfo(); // multicasts an INFO msg to everybody else } for (JChannel ch : Arrays.asList(findChannel(merge_leader_one), findChannel(merge_leader_two))) { MERGE3 merge = (MERGE3) ch.getProtocolStack().findProtocol(MERGE3.class); merge.checkInconsistencies(); } Util.sleep(1000); } for (JChannel ch : Arrays.asList(a, b, c, d)) System.out.println(ch.getName() + ": " + ch.getView()); for (JChannel ch : Arrays.asList(a, b, c, d)) assert ch.getView().size() == 4 : "view of " + ch.getName() + ": " + ch.getView(); }
/** * Creates a list of randomly generated partitions, each having a max size of max_partition_size */ protected List<View> createPartitions(int max_partition_size, JChannel... channels) { long view_id = 1; for (JChannel ch : channels) view_id = Math.max(view_id, ch.getView().getViewId().getId()); List<View> partitions = new ArrayList<>(); List<Address> tmp = new ArrayList<>(); for (JChannel ch : channels) tmp.add(ch.getAddress()); while (!tmp.isEmpty()) { int num_to_remove = (int) Util.random(max_partition_size); List<Address> part = new ArrayList<>(max_partition_size); for (int x = 0; x < num_to_remove && !tmp.isEmpty(); x++) part.add(tmp.remove(0)); partitions.add(new View(part.get(0), view_id + 1, part)); } return partitions; }