/*
* 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.commons.providers.base;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.log4j.Level;
import org.apache.log4j.spi.RootLogger;
import org.apache.sling.discovery.ClusterView;
import org.apache.sling.discovery.DiscoveryService;
import org.apache.sling.discovery.InstanceDescription;
import org.apache.sling.discovery.TopologyEvent;
import org.apache.sling.discovery.TopologyView;
import org.apache.sling.discovery.commons.providers.BaseTopologyView;
import org.apache.sling.discovery.commons.providers.DefaultClusterView;
import org.apache.sling.discovery.commons.providers.DefaultInstanceDescription;
import org.apache.sling.discovery.commons.providers.DummyTopologyView;
import org.apache.sling.discovery.commons.providers.EventHelper;
import org.apache.sling.discovery.commons.providers.spi.ClusterSyncService;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TestViewStateManager {
protected static final Logger logger = LoggerFactory.getLogger(TestViewStateManager.class);
class ClusterSyncServiceWithSemaphore implements ClusterSyncService {
private final Semaphore semaphore;
private final Lock lock;
public ClusterSyncServiceWithSemaphore(Lock lock, Semaphore semaphore) {
this.lock = lock;
this.semaphore = semaphore;
}
@Override
public void sync(BaseTopologyView view, Runnable callback) {
try {
lock.unlock();
try{
logger.info("ClusterSyncServiceWithSemaphore.sync: acquiring lock ...");
semaphore.acquire();
logger.info("ClusterSyncServiceWithSemaphore.sync: lock acquired.");
} finally {
lock.lock();
}
callback.run();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void cancelSync() {
// TODO not implemented yet
}
}
protected ViewStateManagerImpl mgr;
private Random defaultRandom;
private Level logLevel;
@Before
public void setup() throws Exception {
mgr = new ViewStateManagerImpl(new ReentrantLock(), new ClusterSyncService() {
@Override
public void sync(BaseTopologyView view, Runnable callback) {
callback.run();
}
@Override
public void cancelSync() {
// nothing to cancel, we're auto-run
}
});
defaultRandom = new Random(1234123412); // I want randomness yes, but deterministic, for some methods at least
final org.apache.log4j.Logger discoveryLogger = RootLogger.getLogger("org.apache.sling.discovery");
logLevel = discoveryLogger.getLevel();
discoveryLogger.setLevel(Level.INFO);
}
@After
public void teardown() throws Exception {
if (mgr != null) {
// release any async event sender ..
mgr.handleDeactivated();
}
mgr = null;
defaultRandom= null;
final org.apache.log4j.Logger discoveryLogger = RootLogger.getLogger("org.apache.sling.discovery");
discoveryLogger.setLevel(logLevel);
}
void assertEvents(DummyListener listener, TopologyEvent... events) {
TestHelper.assertEvents(mgr, listener, events);
}
/** does couple loops randomly calling handleChanging() (or not) and then handleNewView().
* Note: random is passed to allow customizing and not hardcoding this method to a particular random
* @throws InterruptedException **/
protected void randomEventLoop(final Random random, DummyListener... listeners) throws InterruptedException {
TestHelper.randomEventLoop(mgr, null, 5, -1, random, listeners);
}
@Test
public void testChangedPropertiesChanged() throws Exception {
final DummyListener listener = new DummyListener();
mgr.installMinEventDelayHandler(new DiscoveryService() {
@Override
public TopologyView getTopology() {
throw new IllegalStateException("not yet impl");
}
}, new DummyScheduler(), 1);
mgr.handleActivated();
TestHelper.assertNoEvents(listener);
mgr.bind(listener);
TestHelper.assertNoEvents(listener);
mgr.handleChanging();
TestHelper.assertNoEvents(listener);
final BaseTopologyView view1 = new DummyTopologyView().addInstance();
InstanceDescription instance1 = view1.getInstances().iterator().next();
ClusterView cluster1 = instance1.getClusterView();
mgr.handleNewView(view1);
assertEvents(listener, EventHelper.newInitEvent(view1));
DefaultClusterView cluster2 = new DefaultClusterView(new String(cluster1.getId()));
final BaseTopologyView view2 = new DummyTopologyView(view1.getLocalClusterSyncTokenId()).addInstance(instance1.getSlingId(), cluster2, instance1.isLeader(), instance1.isLocal());
DefaultInstanceDescription instance2 = (DefaultInstanceDescription) view2.getLocalInstance();
instance2.setProperty("foo", "bar");
mgr.handleNewView(view2);
assertEvents(listener, EventHelper.newPropertiesChangedEvent(view1, view2));
}
@Test
public void testDuplicateListeners() throws Exception {
final DummyListener listener = new DummyListener();
mgr.bind(listener);
mgr.bind(listener); // we should be generous and allow duplicate registration
assertTrue(mgr.unbind(listener));
assertFalse(mgr.unbind(listener));
mgr.handleActivated();
assertFalse(mgr.unbind(listener));
mgr.bind(listener);
mgr.bind(listener); // we should be generous and allow duplicate registration
assertTrue(mgr.unbind(listener));
assertFalse(mgr.unbind(listener));
}
@Test
public void testBindActivateChangingChanged() throws Exception {
final DummyListener listener = new DummyListener();
mgr.bind(listener);
TestHelper.assertNoEvents(listener);
mgr.handleActivated();
TestHelper.assertNoEvents(listener);
mgr.handleChanging();
TestHelper.assertNoEvents(listener);
final BaseTopologyView view = new DummyTopologyView().addInstance();
mgr.handleNewView(view);
assertEvents(listener, EventHelper.newInitEvent(view));
randomEventLoop(defaultRandom, listener);
}
@Test
public void testBindChangingActivateChanged() throws Exception {
final DummyListener listener = new DummyListener();
mgr.bind(listener);
TestHelper.assertNoEvents(listener);
mgr.handleChanging();
TestHelper.assertNoEvents(listener);
mgr.handleActivated();
TestHelper.assertNoEvents(listener);
final BaseTopologyView view = new DummyTopologyView().addInstance();
mgr.handleNewView(view);
assertEvents(listener, EventHelper.newInitEvent(view));
randomEventLoop(defaultRandom, listener);
}
@Test
public void testBindChangingChangedActivate() throws Exception {
final DummyListener listener = new DummyListener();
mgr.bind(listener);
TestHelper.assertNoEvents(listener);
mgr.handleChanging();
TestHelper.assertNoEvents(listener);
final BaseTopologyView view = new DummyTopologyView().addInstance();
mgr.handleNewView(view);
TestHelper.assertNoEvents(listener);
mgr.handleActivated();
assertEvents(listener, EventHelper.newInitEvent(view));
randomEventLoop(defaultRandom, listener);
}
@Test
public void testBindChangingChangedChangingActivate() throws Exception {
final DummyListener listener = new DummyListener();
mgr.bind(listener);
TestHelper.assertNoEvents(listener);
mgr.handleChanging();
TestHelper.assertNoEvents(listener);
final BaseTopologyView view = new DummyTopologyView().addInstance();
mgr.handleNewView(view);
TestHelper.assertNoEvents(listener);
mgr.handleChanging();
TestHelper.assertNoEvents(listener);
mgr.handleActivated();
TestHelper.assertNoEvents(listener);
final BaseTopologyView view2 = new DummyTopologyView().addInstance();
mgr.handleNewView(view2);
assertEvents(listener, EventHelper.newInitEvent(view2));
randomEventLoop(defaultRandom, listener);
}
@Test
public void testBindChangedChangingActivate() throws Exception {
final DummyListener listener = new DummyListener();
mgr.bind(listener);
TestHelper.assertNoEvents(listener);
final BaseTopologyView view = new DummyTopologyView().addInstance();
mgr.handleNewView(view);
TestHelper.assertNoEvents(listener);
mgr.handleChanging();
TestHelper.assertNoEvents(listener);
mgr.handleActivated();
TestHelper.assertNoEvents(listener);
final BaseTopologyView view2 = new DummyTopologyView().addInstance();
mgr.handleNewView(view2);
assertEvents(listener, EventHelper.newInitEvent(view2));
randomEventLoop(defaultRandom, listener);
}
@Test
public void testCancelSync() throws Exception {
final List<Runnable> syncCallbacks = new LinkedList<Runnable>();
mgr = new ViewStateManagerImpl(new ReentrantLock(), new ClusterSyncService() {
@Override
public void sync(BaseTopologyView view, Runnable callback) {
synchronized(syncCallbacks) {
syncCallbacks.add(callback);
}
}
@Override
public void cancelSync() {
synchronized(syncCallbacks) {
syncCallbacks.clear();
}
}
});
mgr.handleActivated();
final DummyListener listener = new DummyListener();
mgr.bind(listener);
mgr.handleChanging();
final BaseTopologyView view = new DummyTopologyView().addInstance();
mgr.handleNewView(view);
assertEquals(0, mgr.waitForAsyncEvents(1000));
TestHelper.assertNoEvents(listener);
synchronized(syncCallbacks) {
assertEquals(1, syncCallbacks.size());
}
String id1 = UUID.randomUUID().toString();
String id2 = UUID.randomUUID().toString();
final BaseTopologyView view2 = TestHelper.newView(true, id1, id1, id1, id2);
mgr.handleNewView(view2);
assertEquals(0, mgr.waitForAsyncEvents(1000));
TestHelper.assertNoEvents(listener);
synchronized(syncCallbacks) {
assertEquals(1, syncCallbacks.size());
syncCallbacks.get(0).run();
syncCallbacks.clear();
}
assertEquals(0, mgr.waitForAsyncEvents(1000));
assertEvents(listener, EventHelper.newInitEvent(view2));
}
@Test
public void testActivateBindChangingChanged() throws Exception {
final DummyListener listener = new DummyListener();
// first activate
mgr.handleActivated();
TestHelper.assertNoEvents(listener); // paranoia
// then bind
mgr.bind(listener);
TestHelper.assertNoEvents(listener); // there was no changing or changed yet
mgr.handleChanging();
TestHelper.assertNoEvents(listener);
final BaseTopologyView view = new DummyTopologyView().addInstance();
mgr.handleNewView(view);
assertEvents(listener, EventHelper.newInitEvent(view));
randomEventLoop(defaultRandom, listener);
}
@Test
public void testPropertiesChanged() throws Exception {
final DummyListener listener = new DummyListener();
mgr.handleActivated();
mgr.bind(listener);
mgr.handleChanging();
DummyTopologyView oldView = new DummyTopologyView().addInstance();
DefaultInstanceDescription localInstance =
(DefaultInstanceDescription) oldView.getLocalInstance();
localInstance.setProperty("foo", "bar1");
mgr.handleNewView(oldView);
TopologyEvent initEvent = EventHelper.newInitEvent(oldView.clone());
assertEvents(listener, initEvent);
DummyTopologyView newView = oldView.clone();
oldView.setNotCurrent();
localInstance = (DefaultInstanceDescription) newView.getLocalInstance();
localInstance.setProperty("foo", "bar2");
mgr.handleNewView(newView);
Thread.sleep(2000);
TopologyEvent propertiesChangedEvent = EventHelper.newPropertiesChangedEvent(oldView.clone(), newView.clone());
assertEvents(listener, propertiesChangedEvent);
}
@Test
public void testActivateChangingBindChanged() throws Exception {
final DummyListener listener = new DummyListener();
// first activate
mgr.handleActivated();
TestHelper.assertNoEvents(listener); // paranoia
mgr.handleChanging();
TestHelper.assertNoEvents(listener); // no listener yet
// then bind
mgr.bind(listener);
TestHelper.assertNoEvents(listener); // no changed event yet
final BaseTopologyView view = new DummyTopologyView().addInstance();
mgr.handleNewView(view);
assertEvents(listener, EventHelper.newInitEvent(view));
randomEventLoop(defaultRandom, listener);
}
@Test
public void testActivateChangingChangedBind() throws Exception {
final DummyListener listener = new DummyListener();
// first activate
mgr.handleActivated();
TestHelper.assertNoEvents(listener); // paranoia
mgr.handleChanging();
TestHelper.assertNoEvents(listener); // no listener yet
final BaseTopologyView view = new DummyTopologyView().addInstance();
mgr.handleNewView(view);
TestHelper.assertNoEvents(listener); // no listener yet
// then bind
mgr.bind(listener);
assertEvents(listener, EventHelper.newInitEvent(view));
randomEventLoop(defaultRandom, listener);
}
@Test
public void testBindActivateBindChangingChanged() throws Exception {
final DummyListener listener1 = new DummyListener();
final DummyListener listener2 = new DummyListener();
mgr.bind(listener1);
TestHelper.assertNoEvents(listener1);
mgr.handleActivated();
TestHelper.assertNoEvents(listener1);
mgr.bind(listener2);
TestHelper.assertNoEvents(listener1);
TestHelper.assertNoEvents(listener2);
mgr.handleChanging();
TestHelper.assertNoEvents(listener1);
TestHelper.assertNoEvents(listener2);
final BaseTopologyView view = new DummyTopologyView().addInstance();
mgr.handleNewView(view);
assertEvents(listener1, EventHelper.newInitEvent(view));
assertEvents(listener2, EventHelper.newInitEvent(view));
randomEventLoop(defaultRandom, listener1, listener2);
}
@Test
public void testBindActivateChangingBindChanged() throws Exception {
final DummyListener listener1 = new DummyListener();
final DummyListener listener2 = new DummyListener();
mgr.bind(listener1);
TestHelper.assertNoEvents(listener1);
mgr.handleActivated();
TestHelper.assertNoEvents(listener1);
mgr.handleChanging();
TestHelper.assertNoEvents(listener1);
mgr.bind(listener2);
TestHelper.assertNoEvents(listener1);
TestHelper.assertNoEvents(listener2);
final BaseTopologyView view = new DummyTopologyView().addInstance();
mgr.handleNewView(view);
assertEvents(listener1, EventHelper.newInitEvent(view));
assertEvents(listener2, EventHelper.newInitEvent(view));
randomEventLoop(defaultRandom, listener1, listener2);
}
@Test
public void testActivateBindChangingDuplicateHandleNewView() throws Exception {
final DummyListener listener = new DummyListener();
mgr.handleActivated();
mgr.bind(listener);
mgr.handleChanging();
final DummyTopologyView view = new DummyTopologyView().addInstance();
mgr.handleNewView(view);
assertEvents(listener, EventHelper.newInitEvent(view));
mgr.handleNewView(DummyTopologyView.clone(view));
TestHelper.assertNoEvents(listener);
randomEventLoop(defaultRandom, listener);
}
@Test
public void testActivateBindChangingChangedBindDuplicateHandleNewView() throws Exception {
final DummyListener listener1 = new DummyListener();
mgr.handleActivated();
mgr.bind(listener1);
mgr.handleChanging();
final DummyTopologyView view = new DummyTopologyView().addInstance();
mgr.handleNewView(view);
assertEvents(listener1, EventHelper.newInitEvent(view));
final DummyListener listener2 = new DummyListener();
mgr.bind(listener2);
mgr.handleNewView(DummyTopologyView.clone(view));
TestHelper.assertNoEvents(listener1);
assertEvents(listener2, EventHelper.newInitEvent(view));
randomEventLoop(defaultRandom, listener1, listener2);
}
@Test
public void testActivateChangedBindDuplicateHandleNewView() throws Exception {
final DummyListener listener = new DummyListener();
mgr.handleActivated();
TestHelper.assertNoEvents(listener);
final DummyTopologyView view = new DummyTopologyView().addInstance();
mgr.handleNewView(view);
TestHelper.assertNoEvents(listener);
mgr.bind(listener);
assertEvents(listener, EventHelper.newInitEvent(view));
mgr.handleNewView(DummyTopologyView.clone(view));
TestHelper.assertNoEvents(listener);
randomEventLoop(defaultRandom, listener);
}
@Test
public void testBindActivateChangedChanged() throws Exception {
final DummyListener listener = new DummyListener();
mgr.handleActivated();
TestHelper.assertNoEvents(listener);
mgr.bind(listener);
TestHelper.assertNoEvents(listener);
mgr.handleChanging();
TestHelper.assertNoEvents(listener);
final BaseTopologyView view1 = new DummyTopologyView().addInstance();
mgr.handleNewView(view1);
assertEvents(listener, EventHelper.newInitEvent(view1));
final BaseTopologyView view2 = new DummyTopologyView().addInstance();
mgr.handleNewView(view2);
assertEvents(listener, EventHelper.newChangingEvent(view1), EventHelper.newChangedEvent(view1, view2));
randomEventLoop(defaultRandom, listener);
}
@Test
public void testBindActivateChangedDeactivateChangingActivateChanged() throws Exception {
final DummyListener listener = new DummyListener();
mgr.bind(listener);
TestHelper.assertNoEvents(listener);
mgr.handleActivated();
TestHelper.assertNoEvents(listener);
final BaseTopologyView view1 = new DummyTopologyView().addInstance();
mgr.handleNewView(view1);
assertEvents(listener, EventHelper.newInitEvent(view1));
mgr.handleDeactivated();
TestHelper.assertNoEvents(listener);
mgr.handleChanging();
TestHelper.assertNoEvents(listener);
mgr.bind(listener); // need to bind again after deactivate
mgr.handleActivated();
TestHelper.assertNoEvents(listener);
final BaseTopologyView view2 = new DummyTopologyView().addInstance();
mgr.handleNewView(view2);
assertEvents(listener, EventHelper.newInitEvent(view2));
}
@Test
public void testBindActivateChangedDeactivateChangedActivateChanged() throws Exception {
final DummyListener listener = new DummyListener();
mgr.bind(listener);
TestHelper.assertNoEvents(listener);
mgr.handleActivated();
TestHelper.assertNoEvents(listener);
final BaseTopologyView view1 = new DummyTopologyView().addInstance();
mgr.handleNewView(view1);
assertEvents(listener, EventHelper.newInitEvent(view1));
mgr.handleDeactivated();
TestHelper.assertNoEvents(listener);
final BaseTopologyView view2 = new DummyTopologyView().addInstance();
mgr.handleNewView(view2);
TestHelper.assertNoEvents(listener);
mgr.bind(listener); // need to bind again after deactivate
mgr.handleActivated();
assertEvents(listener, EventHelper.newInitEvent(view2));
final BaseTopologyView view3 = new DummyTopologyView().addInstance();
mgr.handleNewView(view3);
assertEvents(listener, EventHelper.newChangingEvent(view2), EventHelper.newChangedEvent(view2, view3));
}
@Test
public void testBindActivateChangedChangingDeactivateActivateChangingChanged() throws Exception {
final DummyListener listener = new DummyListener();
mgr.bind(listener);
TestHelper.assertNoEvents(listener);
mgr.handleActivated();
TestHelper.assertNoEvents(listener);
final BaseTopologyView view1 = new DummyTopologyView().addInstance();
mgr.handleNewView(view1);
assertEvents(listener, EventHelper.newInitEvent(view1));
mgr.handleChanging();
assertEvents(listener, EventHelper.newChangingEvent(view1));
mgr.handleDeactivated();
TestHelper.assertNoEvents(listener);
mgr.bind(listener); // need to bind again after deactivate
mgr.handleActivated();
TestHelper.assertNoEvents(listener);
mgr.handleChanging();
TestHelper.assertNoEvents(listener);
final BaseTopologyView view2 = new DummyTopologyView().addInstance();
mgr.handleNewView(view2);
assertEvents(listener, EventHelper.newInitEvent(view2));
}
@Test
public void testClusterSyncService_noConcurrency() throws Exception {
final org.apache.log4j.Logger commonsLogger = RootLogger.getLogger("org.apache.sling.discovery.commons.providers");
// final org.apache.log4j.Level logLevel = commonsLogger.getLevel();
commonsLogger.setLevel(Level.INFO); // change here to DEBUG in case of issues with this test
final Semaphore serviceSemaphore = new Semaphore(0);
final ReentrantLock lock = new ReentrantLock();
final ClusterSyncServiceWithSemaphore cs = new ClusterSyncServiceWithSemaphore(lock, serviceSemaphore );
mgr = new ViewStateManagerImpl(lock, cs);
final DummyListener listener = new DummyListener();
mgr.bind(listener);
TestHelper.assertNoEvents(listener);
mgr.handleActivated();
TestHelper.assertNoEvents(listener);
final String slingId1 = UUID.randomUUID().toString();
final String slingId2 = UUID.randomUUID().toString();
final String clusterId = UUID.randomUUID().toString();
final DefaultClusterView cluster = new DefaultClusterView(clusterId);
final DummyTopologyView view1 = new DummyTopologyView()
.addInstance(slingId1, cluster, true, true)
.addInstance(slingId2, cluster, false, false);
async(new Runnable() {
@Override
public void run() {
mgr.handleNewView(view1);
}
});
Thread.sleep(1000);
TestHelper.assertNoEvents(listener);
serviceSemaphore.release(1);
Thread.sleep(1000);
assertEvents(listener, EventHelper.newInitEvent(view1));
final DummyTopologyView view2 = view1.clone();
mgr.handleChanging();
assertEvents(listener, EventHelper.newChangingEvent(view1));
view2.removeInstance(slingId2);
async(new Runnable() {
@Override
public void run() {
mgr.handleNewView(view2);
}
});
logger.debug("run: waiting for 1sec");
Thread.sleep(1000);
logger.debug("run: asserting no events");
TestHelper.assertNoEvents(listener);
logger.debug("run: releasing consistencyService");
serviceSemaphore.release(1);
logger.debug("run: waiting 1sec");
Thread.sleep(1000);
logger.debug("run: asserting 1 event");
assertEvents(listener, EventHelper.newChangedEvent(view1, view2));
commonsLogger.setLevel(Level.INFO); // back to default
}
protected void async(Runnable runnable) {
new Thread(runnable).start();
}
@Test
public void testOnlyDiffersInProperties() throws Exception {
final org.apache.log4j.Logger discoveryLogger = RootLogger.getLogger("org.apache.sling.discovery");
discoveryLogger.setLevel(Level.INFO); // changed from Level.DEBUG
logger.info("testOnlyDiffersInProperties: start");
final String slingId1 = UUID.randomUUID().toString();
final String slingId2 = UUID.randomUUID().toString();
final String slingId3 = UUID.randomUUID().toString();
final String clusterId = UUID.randomUUID().toString();
final DefaultClusterView cluster = new DefaultClusterView(clusterId);
final DummyTopologyView view1 = new DummyTopologyView()
.addInstance(slingId1, cluster, true, true)
.addInstance(slingId2, cluster, false, false)
.addInstance(slingId3, cluster, false, false);
final DummyTopologyView view2 = DummyTopologyView.clone(view1).removeInstance(slingId2);
final DummyTopologyView view3 = DummyTopologyView.clone(view1).removeInstance(slingId2).removeInstance(slingId3);
DummyTopologyView view1Cloned = DummyTopologyView.clone(view1);
logger.info("testOnlyDiffersInProperties: handleNewView(view1)");
mgr.handleNewView(view1);
logger.info("testOnlyDiffersInProperties: handleActivated()");
mgr.handleActivated();
assertEquals(0, mgr.waitForAsyncEvents(5000));
assertFalse(mgr.onlyDiffersInProperties(view1));
assertFalse(mgr.onlyDiffersInProperties(view2));
assertFalse(mgr.onlyDiffersInProperties(view3));
logger.info("testOnlyDiffersInProperties: handleNewView(view2)");
mgr.handleNewView(view2);
assertEquals(0, mgr.waitForAsyncEvents(5000));
assertFalse(mgr.onlyDiffersInProperties(view1));
assertFalse(mgr.onlyDiffersInProperties(view2));
assertFalse(mgr.onlyDiffersInProperties(view3));
logger.info("testOnlyDiffersInProperties: handleNewView(view3)");
mgr.handleNewView(view3);
assertEquals(0, mgr.waitForAsyncEvents(5000));
assertFalse(mgr.onlyDiffersInProperties(view1));
assertFalse(mgr.onlyDiffersInProperties(view2));
assertFalse(mgr.onlyDiffersInProperties(view3));
final DummyTopologyView view4 = DummyTopologyView.clone(view1Cloned);
final DummyTopologyView view5 = DummyTopologyView.clone(view1Cloned);
final DummyTopologyView view6 = DummyTopologyView.clone(view1Cloned);
logger.info("testOnlyDiffersInProperties: handleNewView(view1cloned)");
mgr.handleNewView(view1Cloned);
assertEquals(0, mgr.waitForAsyncEvents(5000));
DefaultInstanceDescription i4_1 = (DefaultInstanceDescription) view4.getInstance(slingId1);
i4_1.setProperty("a", "b");
logger.info("testOnlyDiffersInProperties: onlyDiffersInProperties(view4)");
assertTrue(mgr.onlyDiffersInProperties(view4));
DefaultInstanceDescription i5_1 = (DefaultInstanceDescription) view5.getInstance(slingId1);
i5_1.setProperty("a", "b");
logger.info("testOnlyDiffersInProperties: onlyDiffersInProperties(view5)");
assertTrue(mgr.onlyDiffersInProperties(view5));
DummyTopologyView view4Cloned = DummyTopologyView.clone(view4);
mgr.handleNewView(view4);
assertEquals(0, mgr.waitForAsyncEvents(5000));
logger.info("testOnlyDiffersInProperties: onlyDiffersInProperties(view4Cloned)");
assertFalse(mgr.onlyDiffersInProperties(view4Cloned));
logger.info("testOnlyDiffersInProperties: onlyDiffersInProperties(view5)");
assertFalse(mgr.onlyDiffersInProperties(view5));
DefaultInstanceDescription i6_1 = (DefaultInstanceDescription) view6.getInstance(slingId1);
i6_1.setProperty("a", "c");
logger.info("testOnlyDiffersInProperties: onlyDiffersInProperties(view6)");
assertTrue(mgr.onlyDiffersInProperties(view6));
String originalId = view6.getLocalClusterSyncTokenId();
view6.setId(UUID.randomUUID().toString());
logger.info("testOnlyDiffersInProperties: onlyDiffersInProperties(view6) [2]");
assertFalse(mgr.onlyDiffersInProperties(view6));
view6.setId(originalId);
logger.info("testOnlyDiffersInProperties: onlyDiffersInProperties(view6) [3]");
assertTrue(mgr.onlyDiffersInProperties(view6));
view6.setId(null);
logger.info("testOnlyDiffersInProperties: onlyDiffersInProperties(view6) [4]");
assertFalse(mgr.onlyDiffersInProperties(view6));
view6.setId(originalId);
logger.info("testOnlyDiffersInProperties: onlyDiffersInProperties(view6) [5]");
assertTrue(mgr.onlyDiffersInProperties(view6));
// hack: we're modifying the view *in the ViewStateManagerImpl* here!!:
view4.setId(null);
view6.setId(null);
logger.info("testOnlyDiffersInProperties: onlyDiffersInProperties(view6) [6]");
assertTrue(mgr.onlyDiffersInProperties(view6));
view6.setId(originalId);
logger.info("testOnlyDiffersInProperties: onlyDiffersInProperties(view6) [7]");
assertFalse(mgr.onlyDiffersInProperties(view6));
}
}