Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 141B5200C6E for ; Mon, 8 May 2017 11:00:23 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 12DB5160B99; Mon, 8 May 2017 09:00:23 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id BBAEF160BCA for ; Mon, 8 May 2017 11:00:21 +0200 (CEST) Received: (qmail 65788 invoked by uid 500); 8 May 2017 09:00:21 -0000 Mailing-List: contact commits-help@brooklyn.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@brooklyn.apache.org Delivered-To: mailing list commits@brooklyn.apache.org Received: (qmail 65714 invoked by uid 99); 8 May 2017 09:00:20 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 08 May 2017 09:00:20 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 90743E0005; Mon, 8 May 2017 09:00:20 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: drigodwin@apache.org To: commits@brooklyn.apache.org Date: Mon, 08 May 2017 09:00:23 -0000 Message-Id: <0a4986c9d1f44a89acb7abd118e52873@git.apache.org> In-Reply-To: <335f9a5f7f7d42c089185f90f15cd10c@git.apache.org> References: <335f9a5f7f7d42c089185f90f15cd10c@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [4/5] brooklyn-server git commit: Hide DataGrid inside BrooklynStorageImpl archived-at: Mon, 08 May 2017 09:00:23 -0000 Hide DataGrid inside BrooklynStorageImpl Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/6b59fcb6 Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/6b59fcb6 Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/6b59fcb6 Branch: refs/heads/master Commit: 6b59fcb6a0c8e57dcdd00b8c95ea2b410c8fcf2d Parents: 21c40ba Author: Aled Sage Authored: Thu May 4 11:40:03 2017 +0100 Committer: Aled Sage Committed: Fri May 5 11:23:52 2017 +0100 ---------------------------------------------------------------------- .../core/internal/storage/DataGrid.java | 52 ----------- .../storage/impl/BrooklynStorageImpl.java | 18 +--- .../internal/storage/impl/InmemoryDatagrid.java | 86 ++++++++++++++++++ .../storage/impl/inmemory/InmemoryDatagrid.java | 93 -------------------- .../internal/AbstractManagementContext.java | 3 +- .../storage/impl/BrooklynStorageImplTest.java | 6 +- .../longevity/EntityCleanupLongevityTest.java | 2 +- .../EntityCleanupLongevityTestFixture.java | 48 +++++----- 8 files changed, 120 insertions(+), 188 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6b59fcb6/core/src/main/java/org/apache/brooklyn/core/internal/storage/DataGrid.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/internal/storage/DataGrid.java b/core/src/main/java/org/apache/brooklyn/core/internal/storage/DataGrid.java deleted file mode 100644 index 09f50fb..0000000 --- a/core/src/main/java/org/apache/brooklyn/core/internal/storage/DataGrid.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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.internal.storage; - -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentMap; - -import com.google.common.annotations.VisibleForTesting; - -public interface DataGrid { - - /** - * If a map already exists with this id, returns it; otherwise creates a new map stored - * in the datagrid. - */ - ConcurrentMap getMap(String id); - - /** - * Deletes the map for this id, if it exists; otherwise a no-op. - */ - void remove(String id); - - /** - * Terminates the DataGrid. If there is a real datagrid with multiple machines running, it doesn't mean that the - * datagrid is going to be terminated; it only means that all local resources of the datagrid are released. - */ - void terminate(); - - Map getDatagridMetrics(); - - /** Returns snapshot of known keys at this datagrid */ - @VisibleForTesting - Set getKeys(); - -} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6b59fcb6/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BrooklynStorageImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BrooklynStorageImpl.java b/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BrooklynStorageImpl.java index 60a1e7e..5436b15 100644 --- a/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BrooklynStorageImpl.java +++ b/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BrooklynStorageImpl.java @@ -25,40 +25,28 @@ import java.util.Map; import java.util.concurrent.ConcurrentMap; import org.apache.brooklyn.core.internal.storage.BrooklynStorage; -import org.apache.brooklyn.core.internal.storage.DataGrid; import org.apache.brooklyn.core.internal.storage.Reference; -import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; public class BrooklynStorageImpl implements BrooklynStorage { - private final DataGrid datagrid; + private final InmemoryDatagrid datagrid; private final ConcurrentMap refsMap; private final ConcurrentMap listsMap; private final ConcurrentMap>> refsCache; private final ConcurrentMap>> listRefsCache; - public BrooklynStorageImpl(DataGrid datagrid) { - this.datagrid = datagrid; + public BrooklynStorageImpl() { + this.datagrid = new InmemoryDatagrid(); this.refsMap = datagrid.getMap("refs"); this.listsMap = datagrid.getMap("lists"); this.refsCache = Maps.newConcurrentMap(); this.listRefsCache = Maps.newConcurrentMap(); } - /** - * Returns the DataGrid used by this BrooklynStorageImpl - * - * @return the DataGrid. - */ - @VisibleForTesting - public DataGrid getDataGrid() { - return datagrid; - } - @Override public Reference getReference(final String id) { // Can use different ref instances; no need to always return same one. Caching is an http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6b59fcb6/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/InmemoryDatagrid.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/InmemoryDatagrid.java b/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/InmemoryDatagrid.java new file mode 100644 index 0000000..a63fa3d --- /dev/null +++ b/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/InmemoryDatagrid.java @@ -0,0 +1,86 @@ +/* + * 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.internal.storage.impl; + +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.brooklyn.core.internal.storage.impl.ConcurrentMapAcceptingNullVals; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; + +/** + * A simple implementation of datagrid backed by in-memory (unpersisted) maps, within a single JVM. + * + * @author aled + */ +class InmemoryDatagrid { + + private final Map> maps = Maps.newLinkedHashMap(); + private final AtomicInteger creationCounter = new AtomicInteger(); + + @SuppressWarnings("unchecked") + public ConcurrentMap getMap(String id) { + synchronized (maps) { + ConcurrentMap result = (ConcurrentMap) maps.get(id); + if (result == null) { + result = newMap(); + maps.put(id, result); + creationCounter.incrementAndGet(); + } + return result; + } + } + + // TODO Not doing Maps.newConcurrentMap() because needs to store null values. + // Easy to avoid for Refererence but harder for entity ConfigMap where the user + // can insert null values. + // + // Could write a decorator that switches null values for a null marker, and back again. + // + private ConcurrentMap newMap() { + //return Collections.synchronizedMap(new HashMap()); + return new ConcurrentMapAcceptingNullVals(Maps.newConcurrentMap()); + } + + public void remove(String id) { + synchronized (maps) { + maps.remove(id); + } + } + + public void terminate() { + synchronized (maps) { + maps.clear(); + } + } + + public Map getDatagridMetrics() { + synchronized (maps) { + return ImmutableMap.of("size", maps.size(), "createCount", creationCounter.get()); + } + } + + public Set getKeys() { + return maps.keySet(); + } +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6b59fcb6/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/inmemory/InmemoryDatagrid.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/inmemory/InmemoryDatagrid.java b/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/inmemory/InmemoryDatagrid.java deleted file mode 100644 index 48600d9..0000000 --- a/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/inmemory/InmemoryDatagrid.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * 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.internal.storage.impl.inmemory; - -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.AtomicInteger; - -import org.apache.brooklyn.core.internal.storage.DataGrid; -import org.apache.brooklyn.core.internal.storage.impl.ConcurrentMapAcceptingNullVals; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Maps; - -/** - * A simple implementation of datagrid backed by in-memory (unpersisted) maps, within a single JVM. - * - * @author aled - */ -public class InmemoryDatagrid implements DataGrid { - - private final Map> maps = Maps.newLinkedHashMap(); - private final AtomicInteger creationCounter = new AtomicInteger(); - - @SuppressWarnings("unchecked") - @Override - public ConcurrentMap getMap(String id) { - synchronized (maps) { - ConcurrentMap result = (ConcurrentMap) maps.get(id); - if (result == null) { - result = newMap(); - maps.put(id, result); - creationCounter.incrementAndGet(); - } - return result; - } - } - - // TODO Not doing Maps.newConcurrentMap() because needs to store null values. - // Easy to avoid for Refererence but harder for entity ConfigMap where the user - // can insert null values. - // - // Could write a decorator that switches null values for a null marker, and back again. - // - private ConcurrentMap newMap() { - //return Collections.synchronizedMap(new HashMap()); - return new ConcurrentMapAcceptingNullVals(Maps.newConcurrentMap()); - } - - @Override - public void remove(String id) { - synchronized (maps) { - maps.remove(id); - } - } - - @Override - public void terminate() { - synchronized (maps) { - maps.clear(); - } - } - - @Override - public Map getDatagridMetrics() { - synchronized (maps) { - return ImmutableMap.of("size", maps.size(), "createCount", creationCounter.get()); - } - } - - @Override - public Set getKeys() { - return maps.keySet(); - } - -} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6b59fcb6/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/AbstractManagementContext.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/AbstractManagementContext.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/AbstractManagementContext.java index 45a45d7..c009437 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/AbstractManagementContext.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/AbstractManagementContext.java @@ -61,7 +61,6 @@ import org.apache.brooklyn.core.entity.drivers.downloads.BasicDownloadsManager; import org.apache.brooklyn.core.internal.BrooklynProperties; import org.apache.brooklyn.core.internal.storage.BrooklynStorage; import org.apache.brooklyn.core.internal.storage.impl.BrooklynStorageImpl; -import org.apache.brooklyn.core.internal.storage.impl.inmemory.InmemoryDatagrid; import org.apache.brooklyn.core.location.BasicLocationRegistry; import org.apache.brooklyn.core.mgmt.BrooklynTaskTags; import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContextSequential; @@ -169,7 +168,7 @@ public abstract class AbstractManagementContext implements ManagementContextInte this.catalog = new BasicBrooklynCatalog(this); this.typeRegistry = new BasicBrooklynTypeRegistry(this); - this.storage = new BrooklynStorageImpl(new InmemoryDatagrid()); + this.storage = new BrooklynStorageImpl(); this.rebindManager = new RebindManagerImpl(this); // TODO leaking "this" reference; yuck this.highAvailabilityManager = new HighAvailabilityManagerImpl(this); // TODO leaking "this" reference; yuck http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6b59fcb6/core/src/test/java/org/apache/brooklyn/core/internal/storage/impl/BrooklynStorageImplTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/internal/storage/impl/BrooklynStorageImplTest.java b/core/src/test/java/org/apache/brooklyn/core/internal/storage/impl/BrooklynStorageImplTest.java index 9dc02c5..c90a206 100644 --- a/core/src/test/java/org/apache/brooklyn/core/internal/storage/impl/BrooklynStorageImplTest.java +++ b/core/src/test/java/org/apache/brooklyn/core/internal/storage/impl/BrooklynStorageImplTest.java @@ -29,10 +29,8 @@ import java.util.List; import java.util.Map; import org.apache.brooklyn.core.internal.storage.BrooklynStorage; -import org.apache.brooklyn.core.internal.storage.DataGrid; import org.apache.brooklyn.core.internal.storage.Reference; import org.apache.brooklyn.core.internal.storage.impl.BrooklynStorageImpl; -import org.apache.brooklyn.core.internal.storage.impl.inmemory.InmemoryDatagrid; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -43,15 +41,13 @@ import com.google.common.collect.Lists; public class BrooklynStorageImplTest { - private DataGrid datagrid; private BrooklynStorage storage; @BeforeMethod(alwaysRun=true) public void setUp() throws Exception { // TODO Note that InmemoryDatagrid's ConcurrentMap currently returns snapshot for entrySet() and values() // so the tests here aren't particularly good for confirming it'll work against a real datagrid... - datagrid = new InmemoryDatagrid(); - storage = new BrooklynStorageImpl(datagrid); + storage = new BrooklynStorageImpl(); } @Test http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6b59fcb6/core/src/test/java/org/apache/brooklyn/core/test/qa/longevity/EntityCleanupLongevityTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/test/qa/longevity/EntityCleanupLongevityTest.java b/core/src/test/java/org/apache/brooklyn/core/test/qa/longevity/EntityCleanupLongevityTest.java index 26a45fa..bdc56cf 100644 --- a/core/src/test/java/org/apache/brooklyn/core/test/qa/longevity/EntityCleanupLongevityTest.java +++ b/core/src/test/java/org/apache/brooklyn/core/test/qa/longevity/EntityCleanupLongevityTest.java @@ -53,7 +53,7 @@ public class EntityCleanupLongevityTest extends EntityCleanupLongevityTestFixtur doTestManyTimesAndAssertNoMemoryLeak(JavaClassNames.niceClassAndMethod(), new Runnable() { @Override public void run() { - loc = managementContext.getLocationManager().createLocation(LocationSpec.create(SimulatedLocation.class)); + loc = newLoc(); managementContext.getLocationManager().unmanage(loc); } }); http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6b59fcb6/core/src/test/java/org/apache/brooklyn/core/test/qa/longevity/EntityCleanupLongevityTestFixture.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/test/qa/longevity/EntityCleanupLongevityTestFixture.java b/core/src/test/java/org/apache/brooklyn/core/test/qa/longevity/EntityCleanupLongevityTestFixture.java index 8eeb29e..e8544d8 100644 --- a/core/src/test/java/org/apache/brooklyn/core/test/qa/longevity/EntityCleanupLongevityTestFixture.java +++ b/core/src/test/java/org/apache/brooklyn/core/test/qa/longevity/EntityCleanupLongevityTestFixture.java @@ -18,7 +18,9 @@ */ package org.apache.brooklyn.core.test.qa.longevity; -import java.util.Set; +import static org.testng.Assert.assertTrue; + +import java.util.WeakHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; @@ -29,8 +31,6 @@ import org.apache.brooklyn.api.sensor.SensorEventListener; import org.apache.brooklyn.core.entity.Entities; import org.apache.brooklyn.core.entity.factory.ApplicationBuilder; import org.apache.brooklyn.core.internal.storage.BrooklynStorage; -import org.apache.brooklyn.core.internal.storage.DataGrid; -import org.apache.brooklyn.core.internal.storage.impl.BrooklynStorageImpl; import org.apache.brooklyn.core.location.SimulatedLocation; import org.apache.brooklyn.core.mgmt.internal.AbstractManagementContext; import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext; @@ -50,6 +50,7 @@ import org.testng.annotations.BeforeMethod; import com.google.common.base.Stopwatch; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; public abstract class EntityCleanupLongevityTestFixture { @@ -59,6 +60,9 @@ public abstract class EntityCleanupLongevityTestFixture { protected SimulatedLocation loc; protected TestApplication app; + protected WeakHashMap weakApps; + protected WeakHashMap weakLocs; + // since GC is not definitive (would that it were!) final static long MEMORY_MARGIN_OF_ERROR = 10*1024*1024; @@ -76,6 +80,9 @@ public abstract class EntityCleanupLongevityTestFixture { // do this to ensure GC is initialized managementContext.getExecutionManager(); + + weakApps = new WeakHashMap<>(); + weakLocs = new WeakHashMap<>(); } @AfterMethod(alwaysRun=true) @@ -98,7 +105,8 @@ public abstract class EntityCleanupLongevityTestFixture { long now = timer.elapsed(TimeUnit.MILLISECONDS); System.gc(); System.gc(); String msg = testName+" iteration " + i + " at " + Time.makeTimeStringRounded(now) + " (delta "+Time.makeTimeStringRounded(now-last)+"), using "+ - ((AbstractManagementContext)managementContext).getGarbageCollector().getUsageString(); + ((AbstractManagementContext)managementContext).getGarbageCollector().getUsageString()+ + "; weak-refs app="+Iterables.size(weakApps.keySet())+" and locs="+Iterables.size(weakLocs.keySet()); LOG.info(msg); if (i>=100 && memUsedNearStart<0) { // set this the first time we've run 100 times (let that create a baseline with classes loaded etc) @@ -112,20 +120,6 @@ public abstract class EntityCleanupLongevityTestFixture { BrooklynStorage storage = ((ManagementContextInternal)managementContext).getStorage(); Assert.assertTrue(storage.isMostlyEmpty(), "Not empty storage: "+storage); - DataGrid dg = ((BrooklynStorageImpl)storage).getDataGrid(); - Set keys = dg.getKeys(); - for (String key: keys) { - ConcurrentMap v = dg.getMap(key); - if (v.isEmpty()) continue; - // TODO currently we remember ApplicationUsage - if (key.contains("usage-application")) { - Assert.assertTrue(v.size() <= iterations, "Too many usage-application entries: "+v.size()); - continue; - } - - Assert.fail("Non-empty key in datagrid: "+key+" ("+v+")"); - } - ConcurrentMap schedulers = ((BasicExecutionManager)managementContext.getExecutionManager()).getSchedulerByTag(); // TODO would like to assert this // Assert.assertTrue( schedulers.isEmpty(), "Not empty schedulers: "+schedulers); @@ -134,14 +128,21 @@ public abstract class EntityCleanupLongevityTestFixture { // memory leak detection only applies to subclasses who run lots of iterations if (checkMemoryLeaks()) - assertNoMemoryLeak(memUsedNearStart); + assertNoMemoryLeak(memUsedNearStart, iterations); } - protected void assertNoMemoryLeak(long memUsedPreviously) { + protected void assertNoMemoryLeak(long memUsedPreviously, int iterations) { System.gc(); System.gc(); long memUsedAfter = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); long memChange = memUsedAfter - memUsedPreviously; Assert.assertTrue(memChange < numIterations()*ACCEPTABLE_LEAK_PER_ITERATION + MEMORY_MARGIN_OF_ERROR, "Leaked too much memory: "+Strings.makeJavaSizeString(memChange)); + + // TODO Want a stronger assertion than this - it just says we don't have more apps than we created! + int numApps = Iterables.size(weakApps.keySet()); + assertTrue(numApps <= iterations, "numApps="+numApps+"; iterations="+iterations); + + int numLocs = Iterables.size(weakLocs.keySet()); + assertTrue(numLocs <= iterations, "numLocs="+numLocs+"; iterations="+iterations); } protected void doTestStartAppThenThrowAway(String testName, final boolean stop) { @@ -164,6 +165,7 @@ public abstract class EntityCleanupLongevityTestFixture { protected TestApplication newApp() { final TestApplication result = ApplicationBuilder.newManagedApp(TestApplication.class, managementContext); + weakApps.put(app, null); TestEntity entity = result.createAndManageChild(EntitySpec.create(TestEntity.class)); result.subscriptions().subscribe(entity, TestEntity.NAME, new SensorEventListener() { @Override public void onEvent(SensorEvent event) { @@ -172,4 +174,10 @@ public abstract class EntityCleanupLongevityTestFixture { entity.sensors().set(TestEntity.NAME, "myname"); return result; } + + protected SimulatedLocation newLoc() { + SimulatedLocation result = managementContext.getLocationManager().createLocation(LocationSpec.create(SimulatedLocation.class)); + weakLocs.put(result, null); + return result; + } }