/** Tests the scenario described by Dan in https://issues.jboss.org/browse/JGRP-1876 */ public void testJGRP_1876_Dan() throws Exception { Util.close(d, c, b, a); s = createChannel("S", true); t = createChannel("T", true); u = createChannel("U", true); v = createChannel("V", true); Util.waitUntilAllChannelsHaveSameSize(10000, 500, s, t, u, v); enableInfoSender(false, s, t, u, v); // stops INFO sending in MERGE3 for (JChannel ch : Arrays.asList(s, t, u, v)) System.out.println(ch.getName() + ": " + ch.getView()); View v1 = View.create(s.getAddress(), 10, s.getAddress()); View v2 = View.create(t.getAddress(), 10, t.getAddress()); View v3 = View.create(u.getAddress(), 11, u.getAddress(), v.getAddress()); injectView(v1, s); injectView(v2, t); injectView(v3, u, v); enableInfoSender(false, s, t, u, v); // stops INFO sending in MERGE3 Util.waitUntilAllChannelsHaveSameSize(10000, 500, s); Util.waitUntilAllChannelsHaveSameSize(10000, 500, t); Util.waitUntilAllChannelsHaveSameSize(10000, 500, u, v); System.out.printf("\nPartitions:\n"); for (JChannel ch : Arrays.asList(s, t, u, v)) System.out.println(ch.getName() + ": " + ch.getView()); enableInfoSender(true, s, t, u, v); System.out.println("\nEnabling INFO sending in merge protocols to merge subclusters"); Util.waitUntilAllChannelsHaveSameSize(30000, 1000, s, t, u, v); System.out.println("\nResulting views:"); for (JChannel ch : Arrays.asList(s, t, u, v)) { GMS gms = (GMS) ch.getProtocolStack().findProtocol(GMS.class); View mv = gms.view(); System.out.println(mv); } for (JChannel ch : Arrays.asList(s, t, u, v)) { 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() == 3; } for (JChannel ch : Arrays.asList(s, t, u, v)) { View view = ch.getView(); assert view.size() == 4 : "view should have 4 members: " + view; } }
/** * 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; } }
private List<String> getMemberNames(View view) { List<String> memberNames = new ArrayList<String>(view.size()); for (Address member : view.getMembers()) { memberNames.add(channel.getName(member)); } return memberNames; }
/** * Takes a membership of 10, e.g. {A,B,C,D,E,F,G,H,I,J}, creates multiple partitions (e.g. * {A,B,C}, {D}, {E,F,G,H}, {I,J}), and merges them back into one cluster. Asserts that there's * only 1 MergeView */ public void testMultipleSplits() throws Exception { e = createChannel("E", true); f = createChannel("F", true); g = createChannel("G", true); h = createChannel("H", true); i = createChannel("I", true); j = createChannel("J", true); Util.waitUntilAllChannelsHaveSameSize(10000, 500, a, b, c, d, e, f, g, h, i, j); enableInfoSender(false, a, b, c, d, e, f, g, h, i, j); // stops INFO sending in MERGE3 for (JChannel ch : Arrays.asList(a, b, c, d, e, f, g, h, i, j)) System.out.println(ch.getName() + ": " + ch.getView()); List<View> partitions = createPartitions(4, a, b, c, d, e, f, g, h, i, j); // Install views for (View partition : partitions) { for (Address mbr : partition.getMembersRaw()) { JChannel ch = findChannel(mbr); injectView(partition, ch); } } System.out.printf("\n%d partitions:\n", partitions.size()); for (JChannel ch : Arrays.asList(a, b, c, d, e, f, g, h, i, j)) 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, e, f, g, h, i, j); Util.waitUntilAllChannelsHaveSameSize(30000, 1000, a, b, c, d, e, f, g, h, i, j); System.out.println("\nResulting views:"); for (JChannel ch : Arrays.asList(a, b, c, d, e, f, g, h, i, j)) { 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, e, f, g, h, i, j)) { GMS gms = (GMS) ch.getProtocolStack().findProtocol(GMS.class); View mv = gms.view(); assert mv instanceof MergeView; assert mv.size() == 10; assert ((MergeView) mv).getSubgroups().size() == partitions.size(); } for (JChannel ch : Arrays.asList(a, b, c, d, e, f, g, h, i, j)) { View view = ch.getView(); assert view.size() == 10 : "view should have 10 members: " + view; } }
private Address getAddress(String nodeName) { for (Address member : channel.getView()) { if (channel.getName(member).equals(nodeName)) { return member; } } throw new IllegalArgumentException( "Given node doesn't seem to be a member of the DistributedCommandBus"); }
/** * 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(); }
/** A: {A,B} B: {A,B} C: {C} C receives INFO from B only */ public void testMergeWithIncompleteInfos() throws Exception { Util.close(d); enableInfoSender(false, a, b, c); View one = View.create(a.getAddress(), 10, a.getAddress(), b.getAddress()); View two = View.create(c.getAddress(), 10, c.getAddress()); injectView(one, a, b); injectView(two, c); enableInfoSender(false, a, b, c); Util.waitUntilAllChannelsHaveSameSize(10000, 500, a, b); Util.waitUntilAllChannelsHaveSameSize(10000, 500, c); System.out.printf("\nPartitions:\n"); for (JChannel ch : Arrays.asList(a, b, c)) System.out.println(ch.getName() + ": " + ch.getView()); MERGE3.MergeHeader hdr = MERGE3.MergeHeader.createInfo(one.getViewId(), null, null); Message msg = new Message(null, b.getAddress(), null) .putHeader(merge_id, hdr); // B sends the INFO message to C Event merge_event = new Event(Event.MSG, msg); MERGE3 merge = (MERGE3) c.getProtocolStack().findProtocol(MERGE3.class); merge.up(merge_event); enableInfoSender(true, a, b, c); System.out.println("\nEnabling INFO sending in merge protocols to merge subclusters"); Util.waitUntilAllChannelsHaveSameSize(30000, 1000, a, b, c); System.out.println("\nResulting views:"); for (JChannel ch : Arrays.asList(a, b, c)) { GMS gms = (GMS) ch.getProtocolStack().findProtocol(GMS.class); View mv = gms.view(); System.out.println(mv); } for (JChannel ch : Arrays.asList(a, b, c)) { GMS gms = (GMS) ch.getProtocolStack().findProtocol(GMS.class); View mv = gms.view(); assert mv instanceof MergeView; assert mv.size() == 3; assert ((MergeView) mv).getSubgroups().size() == 2; } for (JChannel ch : Arrays.asList(a, b, c)) { View view = ch.getView(); assert view.size() == 3 : "view should have 3 members: " + view; } }
/** * Tests the scenario described by Dan in https://issues.jboss.org/browse/JGRP-1876; INFO messages * are injected */ public void testJGRP_1876_Dan2() throws Exception { Util.close(d, c, b, a); s = createChannel("S", false); t = createChannel("T", false); u = createChannel("U", false); v = createChannel("V", false); for (JChannel ch : Arrays.asList(s, t, u, v)) ch.getProtocolStack().removeProtocol(MERGE3.class); s.connect("MergeTest4"); t.connect("MergeTest4"); u.connect("MergeTest4"); v.connect("MergeTest4"); Util.waitUntilAllChannelsHaveSameSize(10000, 500, s, t, u, v); for (JChannel ch : Arrays.asList(s, t, u, v)) System.out.println(ch.getName() + ": " + ch.getView()); View v1 = View.create(s.getAddress(), 10, s.getAddress()); View v2 = View.create(t.getAddress(), 10, t.getAddress()); View v3 = View.create(u.getAddress(), 11, u.getAddress(), v.getAddress()); injectView(v1, s); injectView(v2, t); injectView(v3, u, v); Util.waitUntilAllChannelsHaveSameSize(10000, 500, s); Util.waitUntilAllChannelsHaveSameSize(10000, 500, t); Util.waitUntilAllChannelsHaveSameSize(10000, 500, u, v); System.out.printf("\nPartitions:\n"); for (JChannel ch : Arrays.asList(s, t, u, v)) System.out.println(ch.getName() + ": " + ch.getView()); System.out.println("\nInjecting MERGE events into GMS to merge subclusters"); Map<Address, View> different_views = new HashMap<>(); different_views.put(s.getAddress(), v1); different_views.put(t.getAddress(), v2); different_views.put(v.getAddress(), v3); Collection<Address> coords = Util.determineActualMergeCoords(different_views); Address merge_leader = new Membership().add(coords).sort().elementAt(0); System.out.printf("--> coords=%s, merge_leader=%s\n", coords, merge_leader); GMS gms = (GMS) findChannel(merge_leader).getProtocolStack().findProtocol(GMS.class); gms.up(new Event(Event.MERGE, different_views)); Util.waitUntilAllChannelsHaveSameSize(30000, 1000, s, t, u, v); System.out.println("\nResulting views:"); for (JChannel ch : Arrays.asList(s, t, u, v)) { gms = (GMS) ch.getProtocolStack().findProtocol(GMS.class); View mv = gms.view(); System.out.println(mv); } for (JChannel ch : Arrays.asList(s, t, u, v)) { gms = (GMS) ch.getProtocolStack().findProtocol(GMS.class); View mv = gms.view(); assert mv instanceof MergeView; assert mv.size() == 4; assert ((MergeView) mv).getSubgroups().size() == 3; } for (JChannel ch : Arrays.asList(s, t, u, v)) { View view = ch.getView(); assert view.size() == 4 : "view should have 4 members: " + view; } }
/** Tests the scenario described by Karim in https://issues.jboss.org/browse/JGRP-1876 */ public void testJGRP_1876() throws Exception { e = createChannel("E", true); f = createChannel("F", true); g = createChannel("G", true); h = createChannel("H", true); Util.waitUntilAllChannelsHaveSameSize(10000, 500, a, b, c, d, e, f, g, h); enableInfoSender(false, a, b, c, d, e, f, g, h); // stops INFO sending in MERGE3 for (JChannel ch : Arrays.asList(a, b, c, d, e, f, g, h)) System.out.println(ch.getName() + ": " + ch.getView()); View v1 = View.create( a.getAddress(), 10, a.getAddress(), b.getAddress(), c.getAddress(), d.getAddress()); View v2 = View.create( a.getAddress(), 9, a.getAddress(), b.getAddress(), c.getAddress(), d.getAddress(), e.getAddress(), f.getAddress()); View v3 = View.create(g.getAddress(), 8, g.getAddress(), h.getAddress()); injectView(v1, a, b, c, d); injectView(v2, e, f); injectView(v3, g, h); enableInfoSender(false, a, b, c, d, e, f, g, h); // stops INFO sending in MERGE3 Util.waitUntilAllChannelsHaveSameSize(10000, 500, a, b, c, d); for (int x = 0; x < 10; x++) { // can't use waitUntilAllChannelsHaveSameSize() as the channel list's length != view // ! if (e.getView().size() == v2.size() && f.getView().size() == v2.size()) break; Util.sleep(500); } assert e.getView().size() == v2.size() : "E's view: " + e.getView(); assert f.getView().size() == v2.size() : "F's view: " + f.getView(); Util.waitUntilAllChannelsHaveSameSize(10000, 500, g, h); System.out.printf("\nPartitions:\n"); for (JChannel ch : Arrays.asList(a, b, c, d, e, f, g, h)) System.out.println(ch.getName() + ": " + ch.getView()); enableInfoSender(true, a, b, c, d, e, f, g, h); System.out.println("\nEnabling INFO sending in merge protocols to merge subclusters"); Util.waitUntilAllChannelsHaveSameSize(30000, 1000, a, b, c, d, e, f, g, h); System.out.println("\nResulting views:"); for (JChannel ch : Arrays.asList(a, b, c, d, e, f, g, h)) { 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, e, f, g, h)) { GMS gms = (GMS) ch.getProtocolStack().findProtocol(GMS.class); View mv = gms.view(); assert mv instanceof MergeView; assert mv.size() == 8; assert ((MergeView) mv).getSubgroups().size() == 3; } for (JChannel ch : Arrays.asList(a, b, c, d, e, f, g, h)) { View view = ch.getView(); assert view.size() == 8 : "view should have 8 members: " + view; } }
private static void print(JChannel... channels) { for (JChannel ch : channels) { System.out.println(ch.getName() + ": " + ch.getView()); } }