/** Tests a merge between ViewIds of the same coord, e.g. A|6, A|7, A|8, A|9 */ public void testViewsBySameCoord() { View v1 = View.create( a.getAddress(), 6, a.getAddress(), b.getAddress(), c.getAddress(), d.getAddress()); // {A,B,C,D} View v2 = View.create(a.getAddress(), 7, a.getAddress(), b.getAddress(), c.getAddress()); // {A,B,C} View v3 = View.create(a.getAddress(), 8, a.getAddress(), b.getAddress()); // {A,B} View v4 = View.create(a.getAddress(), 9, a.getAddress()); // {A} Util.close(b, c, d); // not interested in those... MERGE3 merge = (MERGE3) a.getProtocolStack().findProtocol(MERGE3.class); for (View view : Arrays.asList(v1, v2, v4, v3)) { MERGE3.MergeHeader hdr = MERGE3.MergeHeader.createInfo(view.getViewId(), null, null); Message msg = new Message(null, a.getAddress(), null).putHeader(merge.getId(), hdr); merge.up(new Event(Event.MSG, msg)); } merge.checkInconsistencies(); // no merge will happen Util.waitUntilAllChannelsHaveSameSize(10000, 500, a); System.out.println("A's view: " + a.getView()); assert a.getView().size() == 1; assert a.getView().containsMember(a.getAddress()); }
/** 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 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(); }
protected void checkInconsistencies(JChannel... channels) { for (JChannel ch : channels) { MERGE3 merge = (MERGE3) ch.getProtocolStack().findProtocol(MERGE3.class); merge.checkInconsistencies(); } }
protected void injectMergeEvents(List<Event> events, JChannel... channels) { for (JChannel ch : channels) { MERGE3 merge = (MERGE3) ch.getProtocolStack().findProtocol(MERGE3.class); for (Event evt : events) merge.up(evt); } }