/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.sling.discovery.base.commons; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.Iterator; import java.util.Set; import java.util.UUID; import org.apache.sling.discovery.InstanceDescription; import org.apache.sling.discovery.InstanceFilter; import org.apache.sling.discovery.TopologyEvent; import org.apache.sling.discovery.TopologyEvent.Type; import org.apache.sling.discovery.base.its.setup.TopologyHelper; import org.apache.sling.discovery.commons.providers.DefaultClusterView; import org.apache.sling.discovery.commons.providers.DefaultInstanceDescription; import org.apache.sling.discovery.commons.providers.spi.LocalClusterView; import org.junit.Test; import junitx.util.PrivateAccessor; public class DefaultTopologyViewTest { @Test public void testForcedLeaderChangeCompare() throws Exception { // create view 1 with first instance the leader final String slingId1 = UUID.randomUUID().toString(); final DefaultTopologyView view1 = TopologyHelper.createTopologyView(UUID .randomUUID().toString(), slingId1); final DefaultInstanceDescription id2 = TopologyHelper.addInstanceDescription(view1, TopologyHelper .createInstanceDescription(view1.getClusterViews().iterator() .next())); final String slingId2 = id2.getSlingId(); final DefaultInstanceDescription id3 = TopologyHelper.addInstanceDescription(view1, TopologyHelper .createInstanceDescription(view1.getClusterViews().iterator() .next())); final String slingId3 = id3.getSlingId(); // now create view 2 with exactly the same instances as above, but the second instance the leader DefaultTopologyView view2 = TopologyHelper.cloneTopologyView(view1, slingId2); // make sure we've chosen a new leader: assertNotEquals(view1.getClusterViews().iterator().next().getLeader().getSlingId(), view2.getClusterViews().iterator().next().getLeader().getSlingId()); // and now test the compare method which should catch the leader change assertTrue(view1.compareTopology(view2)==Type.TOPOLOGY_CHANGED); // same thing now with view3 which takes slingId3 as the leader DefaultTopologyView view3 = TopologyHelper.cloneTopologyView(view1, slingId3); // make sure we've chosen a new leader: assertNotEquals(view1.getClusterViews().iterator().next().getLeader().getSlingId(), view3.getClusterViews().iterator().next().getLeader().getSlingId()); // and now test the compare method which should catch the leader change assertTrue(view1.compareTopology(view3)==Type.TOPOLOGY_CHANGED); } @Test public void testComparelocalClusterSyncTokenId() throws Exception { String clusterViewId = UUID.randomUUID().toString(); String slingId = UUID.randomUUID().toString(); String syncTokenId = UUID.randomUUID().toString(); DefaultTopologyView t1 = createSingleInstanceTopology(slingId, clusterViewId, syncTokenId); DefaultTopologyView t2 = createSingleInstanceTopology(slingId, clusterViewId, syncTokenId); assertNull(t1.compareTopology(t2)); assertNull(t2.compareTopology(t1)); DefaultTopologyView t3 = createSingleInstanceTopology(slingId, clusterViewId, UUID.randomUUID().toString()); assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, t1.compareTopology(t3)); assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, t3.compareTopology(t1)); assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, t2.compareTopology(t3)); assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, t3.compareTopology(t2)); DefaultTopologyView t4 = createSingleInstanceTopology(slingId, clusterViewId, null); assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, t1.compareTopology(t4)); assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, t4.compareTopology(t1)); assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, t2.compareTopology(t4)); assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, t4.compareTopology(t2)); DefaultTopologyView t5 = createSingleInstanceTopology(slingId, clusterViewId, null); assertNull(t5.compareTopology(t4)); assertNull(t4.compareTopology(t5)); } private DefaultTopologyView createSingleInstanceTopology(String slingId, String clusterViewId, String syncTokenId) { LocalClusterView clusterView = new LocalClusterView(clusterViewId, syncTokenId); DefaultInstanceDescription instance = TopologyHelper.createInstanceDescription(slingId, true, clusterView); DefaultTopologyView t = new DefaultTopologyView(); t.setLocalClusterView(clusterView); return t; } @Test public void testCompare() throws Exception { DefaultTopologyView newView = TopologyHelper.createTopologyView(UUID .randomUUID().toString(), UUID.randomUUID().toString()); try { newView.compareTopology(null); fail("Should complain about null"); } catch (Exception e) { // ok } DefaultTopologyView oldView = TopologyHelper .cloneTopologyView(newView); assertNull(newView.compareTopology(oldView)); DefaultInstanceDescription id = TopologyHelper .createInstanceDescription(newView.getClusterViews().iterator() .next()); TopologyHelper.addInstanceDescription(newView, id); assertEquals(Type.TOPOLOGY_CHANGED, newView.compareTopology(oldView)); assertEquals(2, newView.getInstances().size()); // addInstanceDescription now no longer throws an exception if you add // the same // instance twice. this provides greater stability TopologyHelper.addInstanceDescription(newView, id); assertEquals(2, newView.getInstances().size()); // try{ // TopologyTestHelper.addInstanceDescription(newView, id); // fail("should not be able to add twice"); // } catch(Exception e) { // // ok // } oldView = TopologyHelper.cloneTopologyView(newView); assertNull(newView.compareTopology(oldView)); DefaultInstanceDescription instance = (DefaultInstanceDescription) newView.getInstances().iterator().next(); instance.setProperty("a", "b"); assertEquals(Type.PROPERTIES_CHANGED, newView.compareTopology(oldView)); oldView = TopologyHelper.cloneTopologyView(newView); assertNull(newView.compareTopology(oldView)); instance.setProperty("a", "B"); assertEquals(Type.PROPERTIES_CHANGED, newView.compareTopology(oldView)); oldView = TopologyHelper.cloneTopologyView(newView); assertNull(newView.compareTopology(oldView)); instance.setProperty("a", "B"); assertNull(newView.compareTopology(oldView)); // now change the properties of the first instance but modify the second instance' cluster Iterator<InstanceDescription> it = newView.getInstances().iterator(); DefaultInstanceDescription firstInstance = (DefaultInstanceDescription) it.next(); assertNotNull(firstInstance); DefaultInstanceDescription secondInstance = (DefaultInstanceDescription) it.next(); assertNotNull(secondInstance); firstInstance.setProperty("c", "d"); DefaultClusterView cluster = new DefaultClusterView(UUID.randomUUID().toString()); PrivateAccessor.setField(secondInstance, "clusterView", null); cluster.addInstanceDescription(secondInstance); assertEquals(Type.TOPOLOGY_CHANGED, newView.compareTopology(oldView)); } @Test public void testFind() throws Exception { DefaultTopologyView newView = TopologyHelper.createTopologyView(UUID .randomUUID().toString(), UUID.randomUUID().toString()); TopologyHelper.createAndAddInstanceDescription(newView, newView .getClusterViews().iterator().next()); try { newView.findInstances(null); fail("should complain"); } catch (IllegalArgumentException iae) { // ok } final DefaultInstanceDescription id = TopologyHelper .createAndAddInstanceDescription(newView, newView .getClusterViews().iterator().next()); TopologyHelper.createAndAddInstanceDescription(newView, newView .getClusterViews().iterator().next()); assertEquals(4, newView.findInstances(new InstanceFilter() { public boolean accept(InstanceDescription instance) { return true; } }).size()); assertEquals(1, newView.findInstances(new InstanceFilter() { public boolean accept(InstanceDescription instance) { return instance.getSlingId().equals(id.getSlingId()); } }).size()); assertEquals(1, newView.findInstances(new InstanceFilter() { public boolean accept(InstanceDescription instance) { return instance.isLeader(); } }).size()); assertEquals(1, newView.findInstances(new InstanceFilter() { boolean first = true; public boolean accept(InstanceDescription instance) { if (!first) { return false; } first = false; return true; } }).size()); } @Test public void testGetInstances() throws Exception { DefaultTopologyView newView = TopologyHelper.createTopologyView(UUID .randomUUID().toString(), UUID.randomUUID().toString()); Set<InstanceDescription> instances = newView.getInstances(); assertNotNull(instances); try { instances.remove(instances.iterator().next()); fail("list should not be modifiable"); } catch (Exception e) { // ok } } }