You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2015/02/09 16:36:37 UTC

[18/22] incubator-brooklyn git commit: some tests and comments exploring location unmanagement

some tests and comments exploring location unmanagement

as there is a slow leak around locations, no one unmanages them after use by an entity


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/3c97a577
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/3c97a577
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/3c97a577

Branch: refs/heads/master
Commit: 3c97a5774e30be0e9e6b7dfa0fb0613b2cc419e3
Parents: 35142c8
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Mon Feb 9 11:10:10 2015 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Mon Feb 9 11:10:10 2015 +0000

----------------------------------------------------------------------
 .../brooklyn/entity/basic/AbstractEntity.java   |  4 +--
 .../entity/rebind/RebindEntityTest.java         | 27 +++++++++++++++++++-
 .../rebind/RebindLocalhostLocationTest.java     | 22 ++++++++++++++++
 .../entity/rebind/RebindTestFixture.java        | 23 +++++++++++++----
 4 files changed, 68 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3c97a577/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java b/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
index 215b13a..a004bc0 100644
--- a/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
+++ b/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
@@ -770,10 +770,10 @@ public abstract class AbstractEntity extends AbstractBrooklynObject implements E
     public void removeLocations(Collection<? extends Location> removedLocations) {
         synchronized (locations) {
             List<Location> oldLocations = locations.get();
-            Set<Location> truelyRemovedLocations = Sets.intersection(ImmutableSet.copyOf(removedLocations), ImmutableSet.copyOf(oldLocations));
+            Set<Location> trulyRemovedLocations = Sets.intersection(ImmutableSet.copyOf(removedLocations), ImmutableSet.copyOf(oldLocations));
             locations.set(MutableList.<Location>builder().addAll(oldLocations).removeAll(removedLocations).buildImmutable());
             
-            for (Location loc : truelyRemovedLocations) {
+            for (Location loc : trulyRemovedLocations) {
                 emit(AbstractEntity.LOCATION_REMOVED, loc);
             }
         }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3c97a577/core/src/test/java/brooklyn/entity/rebind/RebindEntityTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindEntityTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindEntityTest.java
index ab55346..9b1e05d 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindEntityTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindEntityTest.java
@@ -62,9 +62,11 @@ import brooklyn.event.basic.BasicSensorEvent;
 import brooklyn.event.basic.DependentConfiguration;
 import brooklyn.event.basic.Sensors;
 import brooklyn.location.Location;
+import brooklyn.location.LocationSpec;
 import brooklyn.location.basic.LocationConfigTest.MyLocation;
 import brooklyn.management.ha.ManagementNodeState;
 import brooklyn.management.internal.LocalManagementContext;
+import brooklyn.mementos.BrooklynMementoManifest;
 import brooklyn.mementos.EntityMemento;
 import brooklyn.test.Asserts;
 import brooklyn.test.entity.TestApplication;
@@ -181,7 +183,30 @@ public class RebindEntityTest extends RebindTestFixtureWithApp {
         MyEntity newE = (MyEntity) Iterables.find(newApp.getChildren(), Predicates.instanceOf(MyEntity.class));
         assertEquals(newE.getAttribute(myCustomAttribute), "myval");
     }
-    
+
+    @Test
+    public void testRestoresEntityLocationAndCleansUp() throws Exception {
+        MyLocation loc = origManagementContext.getLocationManager().createLocation(LocationSpec.create(MyLocation.class));
+        origApp.createAndManageChild(EntitySpec.create(MyEntity.class).location(loc));
+        
+        newApp = rebind();
+        MyEntity newE = (MyEntity) Iterables.find(newApp.getChildren(), Predicates.instanceOf(MyEntity.class));
+        
+        Assert.assertEquals(newE.getLocations().size(), 1); 
+        Location loc2 = Iterables.getOnlyElement(newE.getLocations());
+        Assert.assertEquals(loc, loc2);
+        Assert.assertFalse(loc==loc2);
+        
+        newApp.stop();
+        // TODO how to trigger automatic unmanagement? see notes in RebindLocalhostLocationTest
+        newManagementContext.getLocationManager().unmanage(loc2);
+        switchOriginalToNewManagementContext();
+        RebindTestUtils.waitForPersisted(origManagementContext);
+        
+        BrooklynMementoManifest mf = loadMementoManifest();
+        Assert.assertTrue(mf.getLocationIdToType().isEmpty(), "Expected no locations; had "+mf.getLocationIdToType());
+    }
+
     @Test
     public void testRestoresEntityIdAndDisplayName() throws Exception {
         MyEntity origE = origApp.createAndManageChild(EntitySpec.create(MyEntity.class)

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3c97a577/core/src/test/java/brooklyn/entity/rebind/RebindLocalhostLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindLocalhostLocationTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindLocalhostLocationTest.java
index 16fc7fc..00e88d7 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindLocalhostLocationTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindLocalhostLocationTest.java
@@ -24,12 +24,14 @@ import java.util.Collections;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.testng.Assert;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.location.LocationSpec;
 import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.location.basic.SshMachineLocation;
+import brooklyn.mementos.BrooklynMementoManifest;
 import brooklyn.test.entity.TestApplication;
 
 import com.google.common.collect.ImmutableList;
@@ -79,5 +81,25 @@ public class RebindLocalhostLocationTest extends RebindTestFixtureWithApp {
         SshMachineLocation newChildLoc = (SshMachineLocation) Iterables.get(newLoc.getChildren(), 0);
         assertEquals(newChildLoc.execScript(Collections.<String,Object>emptyMap(), "mysummary", ImmutableList.of("true")), 0);
     }
+
+    @Test(groups="Integration")
+    public void testMachineCleansUp() throws Exception {
+        testMachineUsableAfterRebind();
+        newApp.stop();
+
+        switchOriginalToNewManagementContext();
+        
+        // TODO how should we automatically unmanage these?
+        // (in this test, locations are created manually, so probably should be destroyed manually, 
+        // but in most cases we should probably unmanage the location as part of the entity;
+        // could keep the entity ID only in the location, then safely reverse-check usages?)
+        // see related non-integration test in RebindEntityTest
+        origManagementContext.getLocationManager().unmanage(origLoc);
+        
+        RebindTestUtils.waitForPersisted(origManagementContext);
+        
+        BrooklynMementoManifest mf = loadMementoManifest();
+        Assert.assertTrue(mf.getLocationIdToType().isEmpty(), "Expected no locations; had "+mf.getLocationIdToType());
+    }
     
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3c97a577/core/src/test/java/brooklyn/entity/rebind/RebindTestFixture.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindTestFixture.java b/core/src/test/java/brooklyn/entity/rebind/RebindTestFixture.java
index 39004f6..8f1c1c6 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindTestFixture.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindTestFixture.java
@@ -107,7 +107,7 @@ public abstract class RebindTestFixture<T extends StartableApplication> {
     protected void switchOriginalToNewManagementContext() {
         origManagementContext.getRebindManager().stopPersistence();
         for (Application e: origManagementContext.getApplications()) ((Startable)e).stop();
-        waitForTaskCountToBecome(origManagementContext, 0);
+        waitForTaskCountToBecome(origManagementContext, 0, true);
         origManagementContext.terminate();
         origManagementContext = (LocalManagementContext) newManagementContext;
         origApp = newApp;
@@ -116,19 +116,32 @@ public abstract class RebindTestFixture<T extends StartableApplication> {
     }
 
     public static void waitForTaskCountToBecome(final ManagementContext mgmt, final int allowedMax) {
+        waitForTaskCountToBecome(mgmt, allowedMax, false);
+    }
+    
+    public static void waitForTaskCountToBecome(final ManagementContext mgmt, final int allowedMax, final boolean skipKnownBackgroundTasks) {
         Repeater.create().every(Duration.millis(20)).limitTimeTo(Duration.TEN_SECONDS).until(new Callable<Boolean>() {
             @Override
             public Boolean call() throws Exception {
                 ((LocalManagementContext)mgmt).getGarbageCollector().gcIteration();
                 long taskCountAfterAtOld = ((BasicExecutionManager)mgmt.getExecutionManager()).getNumIncompleteTasks();
                 List<Task<?>> tasks = ((BasicExecutionManager)mgmt.getExecutionManager()).getAllTasks();
-                int unendedTasks = 0;
+                int unendedTasks = 0, extraAllowedMax = 0;
                 for (Task<?> t: tasks) {
-                    if (!t.isDone()) unendedTasks++;
+                    if (!t.isDone()) {
+                        if (skipKnownBackgroundTasks) {
+                            if (t.toString().indexOf("ssh-location cache cleaner")>=0) {
+                                extraAllowedMax++;
+                            }
+                        }
+                        unendedTasks++;
+                    }
                 }
-                LOG.info("Count of incomplete tasks now "+taskCountAfterAtOld+", "+unendedTasks+" unended; tasks remembered are: "+
+                LOG.info("Count of incomplete tasks now "+taskCountAfterAtOld+", "+unendedTasks+" unended"
+                    + (extraAllowedMax>0 ? " ("+extraAllowedMax+" allowed)" : "")
+                    + "; tasks remembered are: "+
                     tasks);
-                return taskCountAfterAtOld<=allowedMax;
+                return taskCountAfterAtOld<=allowedMax+extraAllowedMax;
             }
         }).runRequiringTrue();
     }