/* * 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.brooklyn.core.mgmt.rebind; import static org.testng.Assert.assertTrue; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.brooklyn.api.entity.Entity; import org.apache.brooklyn.api.entity.EntitySpec; import org.apache.brooklyn.api.mgmt.ManagementContext; import org.apache.brooklyn.api.mgmt.rebind.mementos.EntityMemento; import org.apache.brooklyn.api.mgmt.rebind.mementos.TreeNode; import org.apache.brooklyn.api.objs.Identifiable; import org.apache.brooklyn.core.entity.Entities; import org.apache.brooklyn.core.mgmt.rebind.RebindManagerImpl; import org.apache.brooklyn.core.mgmt.rebind.dto.MementosGenerators; import org.apache.brooklyn.core.test.entity.TestApplication; import org.apache.brooklyn.core.test.entity.TestEntity; import org.apache.brooklyn.util.collections.MutableSet; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import com.google.common.collect.ImmutableList; import com.google.common.collect.Maps; public class RebindManagerSorterTest { private TestApplication app; @SuppressWarnings("unused") private ManagementContext managementContext; private Set<ManagementContext> mgmts = MutableSet.of(); @BeforeMethod(alwaysRun=true) public void setUp() throws Exception { app = TestApplication.Factory.newManagedInstanceForTests(); mgmts.add(managementContext = app.getManagementContext()); } @AfterMethod(alwaysRun=true) public void tearDown() throws Exception { for (ManagementContext m: mgmts) Entities.destroyAll(m); mgmts.clear(); } @Test public void testSortOrder() throws Exception { TestEntity e1a = app.createAndManageChild(EntitySpec.create(TestEntity.class)); TestEntity e1b = e1a.createAndManageChild(EntitySpec.create(TestEntity.class)); // In reverse order Map<String, EntityMemento> nodes = toMementos(ImmutableList.of(e1b, e1a, app)); Map<String, EntityMemento> sortedNodes = RebindManagerImpl.sortParentFirst(nodes); assertOrder(sortedNodes, ImmutableList.of(app, e1a, e1b)); // already in correct order Map<String, EntityMemento> nodes2 = toMementos(ImmutableList.of(app, e1a, e1b)); Map<String, EntityMemento> sortedNodes2 = RebindManagerImpl.sortParentFirst(nodes2); assertOrder(sortedNodes2, ImmutableList.of(app, e1a, e1b)); } @Test public void testSortOrderMultipleBranches() throws Exception { TestEntity e1a = app.createAndManageChild(EntitySpec.create(TestEntity.class)); TestEntity e1b = e1a.createAndManageChild(EntitySpec.create(TestEntity.class)); TestEntity e2a = app.createAndManageChild(EntitySpec.create(TestEntity.class)); TestEntity e2b = e2a.createAndManageChild(EntitySpec.create(TestEntity.class)); Map<String, EntityMemento> nodes = toMementos(ImmutableList.of(e2b, e1b, e2a, e1a, app)); Map<String, EntityMemento> sortedNodes = RebindManagerImpl.sortParentFirst(nodes); assertOrder(sortedNodes, ImmutableList.of(app, e1a, e1b), ImmutableList.of(app, e2a, e2b)); } @Test public void testSortOrderMultipleApps() throws Exception { TestApplication app2 = TestApplication.Factory.newManagedInstanceForTests(); mgmts.add(app2.getManagementContext()); TestEntity e1a = app.createAndManageChild(EntitySpec.create(TestEntity.class)); TestEntity e1b = e1a.createAndManageChild(EntitySpec.create(TestEntity.class)); TestEntity e2a = app2.createAndManageChild(EntitySpec.create(TestEntity.class)); TestEntity e2b = e2a.createAndManageChild(EntitySpec.create(TestEntity.class)); Map<String, EntityMemento> nodes = toMementos(ImmutableList.of(e2b, e1b, e2a, e1a, app, app2)); Map<String, EntityMemento> sortedNodes = RebindManagerImpl.sortParentFirst(nodes); assertOrder(sortedNodes, ImmutableList.of(app, e1a, e1b), ImmutableList.of(app2, e2a, e2b)); } @Test public void testSortOrderWhenNodesMissing() throws Exception { TestEntity e1a = app.createAndManageChild(EntitySpec.create(TestEntity.class)); TestEntity e1b = e1a.createAndManageChild(EntitySpec.create(TestEntity.class)); Map<String, EntityMemento> nodes = toMementos(ImmutableList.of(e1b, e1a)); Map<String, EntityMemento> sortedNodes = RebindManagerImpl.sortParentFirst(nodes); assertOrder(sortedNodes, ImmutableList.of(e1a, e1b)); } @SuppressWarnings("unchecked") private void assertOrder(Map<String, ? extends TreeNode> nodes, Iterable<? extends Identifiable> order) { assertOrders(nodes, order); } @SuppressWarnings("unchecked") private void assertOrder(Map<String, ? extends TreeNode> nodes, Iterable<? extends Identifiable> order1, Iterable<? extends Identifiable> order2) { assertOrders(nodes, order1, order2); } private void assertOrders(Map<String, ? extends TreeNode> nodes, Iterable<? extends Identifiable>... orders) { List<String> actualOrder = ImmutableList.copyOf(nodes.keySet()); String errmsg = "actualOrder="+actualOrder+"; requiredSubOrderings="+Arrays.toString(orders); for (Iterable<? extends Identifiable> order : orders) { int prevIndex = -1; for (Identifiable o : order) { int index = actualOrder.indexOf(o.getId()); assertTrue(index > prevIndex, errmsg); prevIndex = index; } } } private Map<String, EntityMemento> toMementos(Iterable<? extends Entity> entities) { Map<String, EntityMemento> result = Maps.newLinkedHashMap(); for (Entity entity : entities) { result.put(entity.getId(), MementosGenerators.newEntityMemento(Entities.deproxy(entity))); } return result; } }