/** 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; } }
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); } }