brooklyn-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hadr...@apache.org
Subject [06/33] incubator-brooklyn git commit: [BROOKLYN-162] Refactor package in ./core/management
Date Sat, 15 Aug 2015 13:33:08 GMT
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/test/java/brooklyn/management/osgi/OsgiVersionMoreEntityTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/management/osgi/OsgiVersionMoreEntityTest.java b/core/src/test/java/brooklyn/management/osgi/OsgiVersionMoreEntityTest.java
deleted file mode 100644
index 0877ed5..0000000
--- a/core/src/test/java/brooklyn/management/osgi/OsgiVersionMoreEntityTest.java
+++ /dev/null
@@ -1,459 +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 brooklyn.management.osgi;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.util.Arrays;
-import java.util.List;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.launch.Framework;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-import org.apache.brooklyn.api.basic.BrooklynObject;
-import org.apache.brooklyn.api.catalog.CatalogItem;
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.api.management.classloading.BrooklynClassLoadingContext;
-import org.apache.brooklyn.api.policy.PolicySpec;
-
-import brooklyn.catalog.internal.CatalogEntityItemDto;
-import brooklyn.catalog.internal.CatalogItemBuilder;
-import brooklyn.catalog.internal.CatalogItemDtoAbstract;
-import brooklyn.catalog.internal.CatalogTestUtils;
-import brooklyn.catalog.internal.CatalogUtils;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.effector.Effectors;
-import brooklyn.entity.proxying.InternalEntityFactory;
-import brooklyn.entity.proxying.InternalPolicyFactory;
-import brooklyn.management.internal.LocalManagementContext;
-import brooklyn.management.internal.ManagementContextInternal;
-
-import org.apache.brooklyn.test.TestResourceUnavailableException;
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.apache.brooklyn.test.entity.TestApplication;
-
-import brooklyn.util.guava.Maybe;
-import brooklyn.util.os.Os;
-import brooklyn.util.osgi.Osgis;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-
-
-/** 
- * Tests that OSGi entities load correctly and have the right catalog information set.
- * Note further tests done elsewhere using CAMP YAML (referring to methods in this class).
- */
-public class OsgiVersionMoreEntityTest {
-   
-    public static final String BROOKLYN_TEST_OSGI_ENTITIES_PATH = OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH;
-    public static final String BROOKLYN_TEST_OSGI_ENTITIES_URL = "classpath:"+OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH;
-
-    public static final String BROOKLYN_TEST_MORE_ENTITIES_V1_PATH = OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_V1_PATH;
-    public static final String BROOKLYN_TEST_MORE_ENTITIES_V1_URL = "classpath:"+BROOKLYN_TEST_MORE_ENTITIES_V1_PATH;
-    public static final String BROOKLYN_TEST_MORE_ENTITIES_V2_PATH = OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_V2_PATH;
-    public static final String BROOKLYN_TEST_MORE_ENTITIES_V2_URL = "classpath:"+BROOKLYN_TEST_MORE_ENTITIES_V2_PATH;
-    public static final String BROOKLYN_TEST_MORE_ENTITIES_V2_EVIL_TWIN_PATH = OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_V2_EVIL_TWIN_PATH;
-    public static final String BROOKLYN_TEST_MORE_ENTITIES_V2_EVIL_TWIN_URL = "classpath:"+BROOKLYN_TEST_MORE_ENTITIES_V2_EVIL_TWIN_PATH;
-    
-    public static final String TEST_VERSION = "0.1.0";
-
-    public static final String EXPECTED_SAY_HI_BROOKLYN_RESPONSE_FROM_V1 = "Hi BROOKLYN from V1";
-    public static final String EXPECTED_SAY_HI_BROOKLYN_RESPONSE_FROM_V2 = "HI BROOKLYN FROM V2";
-    public static final String EXPECTED_SAY_HI_BROOKLYN_RESPONSE_FROM_V2_EVIL_TWIN = "HO BROOKLYN FROM V2 EVIL TWIN";
-    
-    protected LocalManagementContext mgmt;
-    protected TestApplication app;
-
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        mgmt = LocalManagementContextForTests.builder(true).disableOsgi(false).build();
-        app = TestApplication.Factory.newManagedInstanceForTests(mgmt);
-    }
-
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws BundleException, IOException, InterruptedException {
-        Entities.destroyAll(mgmt);
-    }
-    
-    /**
-     * Test fix for
-     * java.lang.NoClassDefFoundError: brooklyn.event.AttributeSensor not found by io.brooklyn.brooklyn-test-osgi-entities [41]
-     */
-    @Test
-    public void testEntityProxy() throws Exception {
-        File storageTempDir = Os.newTempDir("osgi-standalone");
-        Framework framework = Osgis.newFrameworkStarted(storageTempDir.getAbsolutePath(), true, null);
-        
-        try {
-            ManagementContextInternal managementContext;
-            InternalEntityFactory factory;
-
-            managementContext = new LocalManagementContextForTests();
-            InternalPolicyFactory policyFactory = new InternalPolicyFactory(managementContext);
-            factory = new InternalEntityFactory(managementContext, managementContext.getEntityManager().getEntityTypeRegistry(), policyFactory);
-
-            TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-            Bundle bundle = Osgis.install(framework, BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-            @SuppressWarnings("unchecked")
-            Class<? extends Entity> bundleCls = (Class<? extends Entity>) bundle.loadClass("brooklyn.osgi.tests.SimpleEntityImpl");
-            @SuppressWarnings("unchecked")
-            Class<? extends Entity> bundleInterface = (Class<? extends Entity>) bundle.loadClass("brooklyn.osgi.tests.SimpleEntity");
-
-            @SuppressWarnings("unchecked")
-            EntitySpec<Entity> spec = (EntitySpec<Entity>) (((EntitySpec<Entity>)EntitySpec.create(bundleInterface))).impl(bundleCls);
-            Entity entity = bundleCls.newInstance();
-            factory.createEntityProxy(spec, entity);
-
-            if (managementContext != null) Entities.destroyAll(managementContext);
-        } finally {
-            OsgiStandaloneTest.tearDownOsgiFramework(framework, storageTempDir);
-        }
-    }
-    
-    protected CatalogItem<?, ?> addCatalogItemWithTypeAsName(String type, String version, String ...libraries) {
-        return addCatalogItemWithNameAndType(type, version, type, libraries);
-    }
-    protected CatalogItem<?, ?> addCatalogItemWithNameAndType(String symName, String version, String type, String ...libraries) {
-        return addCatalogItemWithNameAndType(mgmt, symName, version, type, libraries);
-    }
-
-    @SuppressWarnings("deprecation")
-    static CatalogItem<?, ?> addCatalogItemWithNameAndType(ManagementContext mgmt, String symName, String version, String type, String ...libraries) {
-        CatalogEntityItemDto c1 = newCatalogItemWithNameAndType(symName, version, type, libraries);
-        mgmt.getCatalog().addItem(c1);
-        CatalogItem<?, ?> c2 = mgmt.getCatalog().getCatalogItem(symName, version);
-        Preconditions.checkNotNull(c2, "Item "+type+":"+version+" was not found after adding it");
-        return c2;
-    }
-
-    static CatalogEntityItemDto newCatalogItemWithTypeAsName(String type, String version, String ...libraries) {
-        return newCatalogItemWithNameAndType(type, version, type, libraries);
-    }
-    static CatalogEntityItemDto newCatalogItemWithNameAndType(String symName, String version, String type, String ...libraries) {
-        @SuppressWarnings("deprecation")
-        CatalogEntityItemDto c1 = CatalogItemBuilder.newEntity(symName, version)
-                .javaType(type)
-                .libraries(CatalogItemDtoAbstract.parseLibraries(Arrays.asList(libraries)))
-                .build();
-        return c1;
-    }
-
-    protected Entity addItemFromCatalog(CatalogItem<?, ?> c2) {
-        return addItemFromCatalog(mgmt, app, c2);
-    }
-    
-    public static Entity addItemFromCatalog(ManagementContext mgmt, TestApplication parent, CatalogItem<?, ?> c2) {
-        return parent.createAndManageChild( CatalogTestUtils.createEssentialEntitySpec(mgmt, c2) );
-    }
-
-    public static void assertV1MethodCall(Entity me) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
-        Assert.assertEquals(doMethodCallBrooklyn(me), EXPECTED_SAY_HI_BROOKLYN_RESPONSE_FROM_V1);
-    }
-    public static void assertV2MethodCall(BrooklynObject me) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
-        Assert.assertEquals(doMethodCallBrooklyn(me), EXPECTED_SAY_HI_BROOKLYN_RESPONSE_FROM_V2);
-    }
-    public static void assertV2EvilTwinMethodCall(Entity me) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
-        Assert.assertEquals(doMethodCallBrooklyn(me), EXPECTED_SAY_HI_BROOKLYN_RESPONSE_FROM_V2_EVIL_TWIN);
-    }
-
-    public static Object doMethodCallBrooklyn(BrooklynObject me) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
-        return me.getClass().getMethod("sayHI", String.class).invoke(me, "Brooklyn");
-    }
-
-    public static void assertV1EffectorCall(Entity me) {
-        Assert.assertEquals(doEffectorCallBrooklyn(me), EXPECTED_SAY_HI_BROOKLYN_RESPONSE_FROM_V1);
-    }
-    public static void assertV2EffectorCall(Entity me) {
-        Assert.assertEquals(doEffectorCallBrooklyn(me), EXPECTED_SAY_HI_BROOKLYN_RESPONSE_FROM_V2);
-    }
-    public static void assertV2EvilTwinEffectorCall(Entity me) {
-        Assert.assertEquals(doEffectorCallBrooklyn(me), EXPECTED_SAY_HI_BROOKLYN_RESPONSE_FROM_V2_EVIL_TWIN);
-    }
-
-    public static String doEffectorCallBrooklyn(Entity me) {
-        return me.invoke(Effectors.effector(String.class, "sayHI").buildAbstract(), ImmutableMap.of("name", "brooklyn")).getUnchecked();
-    }
-
-    public static CatalogItem<?, ?> addMoreEntityV1(ManagementContext mgmt, String versionToRegister) {
-        TestResourceUnavailableException.throwIfResourceUnavailable(OsgiVersionMoreEntityTest.class, BROOKLYN_TEST_MORE_ENTITIES_V1_PATH);
-        return addCatalogItemWithNameAndType(mgmt,
-            OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY,
-            versionToRegister,
-            OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY,
-            BROOKLYN_TEST_MORE_ENTITIES_V1_URL);
-    }
-    public static CatalogItem<?, ?> addMoreEntityV2(ManagementContext mgmt, String versionToRegister) {
-        TestResourceUnavailableException.throwIfResourceUnavailable(OsgiVersionMoreEntityTest.class, BROOKLYN_TEST_MORE_ENTITIES_V1_PATH);
-        return addCatalogItemWithNameAndType(mgmt,
-            OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY,
-            versionToRegister,
-            OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY,
-            BROOKLYN_TEST_MORE_ENTITIES_V2_URL,
-            BROOKLYN_TEST_OSGI_ENTITIES_URL);
-    }
-    
-    @Test
-    public void testMoreEntitiesV1() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), BROOKLYN_TEST_MORE_ENTITIES_V1_PATH);
-
-        CatalogItem<?, ?> c2 = addMoreEntityV1(mgmt, TEST_VERSION);
-        
-        // test load and instantiate
-        Entity me = addItemFromCatalog(c2);
-        Assert.assertEquals(me.getCatalogItemId(), CatalogUtils.getVersionedId(OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY, TEST_VERSION));
-        
-        assertV1MethodCall(me);
-        assertV1EffectorCall(me);
-        
-        // test adding a child gets the right type; this time by entity parent hierarchy
-        BrooklynClassLoadingContext loader = CatalogUtils.newClassLoadingContext(mgmt, c2);
-        @SuppressWarnings({ "unchecked", "rawtypes" })
-        Entity me2 = me.addChild(EntitySpec.create( (Class)loader.loadClass(c2.getJavaType()) ));
-        Assert.assertEquals(me2.getCatalogItemId(), CatalogUtils.getVersionedId(OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY, TEST_VERSION));
-    }
-
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    protected PolicySpec<?> getPolicySpec(CatalogItem<?, ?> cp) {
-        BrooklynClassLoadingContext loader = CatalogUtils.newClassLoadingContext(mgmt, cp);
-        PolicySpec spec = PolicySpec.create( (Class)loader.loadClass(cp.getJavaType()) );
-        spec.catalogItemId(cp.getId());
-        return spec;
-    }
-
-    @Test
-    public void testMoreEntitiesV1Policy() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), BROOKLYN_TEST_MORE_ENTITIES_V1_PATH);
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        CatalogItem<?, ?> c2 = addCatalogItemWithTypeAsName(
-                OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY,
-                TEST_VERSION,
-                BROOKLYN_TEST_MORE_ENTITIES_V1_URL);
-        
-        // test load and instantiate
-        Entity me = addItemFromCatalog(c2);
-
-        CatalogItem<?, ?> cp = addCatalogItemWithTypeAsName(
-                OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_SIMPLE_POLICY,
-                TEST_VERSION,
-                BROOKLYN_TEST_OSGI_ENTITIES_URL);
-        me.addPolicy(getPolicySpec(cp));
-        
-        Assert.assertEquals(me.getPolicies().size(), 1, "Wrong number of policies: "+me.getPolicies());
-        
-        String catalogItemId = Iterables.getOnlyElement( me.getPolicies() ).getCatalogItemId();
-        Assert.assertNotNull(catalogItemId);
-        // must be the actual source bundle
-        Assert.assertFalse(catalogItemId.equals(me.getCatalogItemId()), "catalog item id is: "+catalogItemId);
-        Assert.assertTrue(catalogItemId.equals(CatalogUtils.getVersionedId(OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_SIMPLE_POLICY, TEST_VERSION)), "catalog item id is: "+catalogItemId);
-    }
-
-    @Test
-    public void testMoreEntitiesV2FailsWithoutBasicTestOsgiEntitiesBundle() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), BROOKLYN_TEST_MORE_ENTITIES_V2_PATH);
-
-        CatalogItem<?, ?> c2 = addCatalogItemWithTypeAsName(
-                OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY,
-                TEST_VERSION,
-                BROOKLYN_TEST_MORE_ENTITIES_V2_URL);
-        
-        // test load and instantiate
-        try {
-            Entity me = addItemFromCatalog(c2);
-            Assert.fail("Should have failed, with unresolved dependency; instead got "+me);
-        } catch (Exception e) {
-            Assert.assertTrue(e.toString().toLowerCase().contains("unresolved constraint"), "Missing expected text in error: "+e);
-            Assert.assertTrue(e.toString().toLowerCase().contains("wiring.package"), "Missing expected text in error: "+e);
-            Assert.assertTrue(e.toString().toLowerCase().contains("brooklyn.osgi.tests"), "Missing expected text in error: "+e);
-        }
-    }
-    
-    // V2 works with dependency declared, and can load
-    // and has policy, with policy item catalog ID is reasonable
-    @Test
-    public void testMoreEntitiesV2() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), BROOKLYN_TEST_MORE_ENTITIES_V2_PATH);
-
-        CatalogItem<?, ?> c2 = addCatalogItemWithTypeAsName(
-                OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY,
-                TEST_VERSION,
-                BROOKLYN_TEST_MORE_ENTITIES_V2_URL,
-                BROOKLYN_TEST_OSGI_ENTITIES_URL);
-        
-        // test load and instantiate
-        Entity me = addItemFromCatalog(c2);
-        Assert.assertEquals(me.getCatalogItemId(), CatalogUtils.getVersionedId(OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY, TEST_VERSION));
-        
-        assertV2MethodCall(me);
-        assertV2EffectorCall(me);
-        Assert.assertEquals(me.getPolicies().size(), 1, "Wrong number of policies: "+me.getPolicies());
-        
-        String catalogItemId = Iterables.getOnlyElement( me.getPolicies() ).getCatalogItemId();
-        Assert.assertNotNull(catalogItemId);
-        // allow either me's bundle (more) or the actual source bundle
-        Assert.assertTrue(catalogItemId.equals(me.getCatalogItemId()) || catalogItemId.startsWith("brooklyn-test-osgi-entities"));
-    }
-
-    @Test
-    public void testMoreEntitiesV1ThenV2GivesV2() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), BROOKLYN_TEST_MORE_ENTITIES_V1_PATH);
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), BROOKLYN_TEST_MORE_ENTITIES_V2_PATH);
-
-        addCatalogItemWithTypeAsName(
-                OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY,
-                TEST_VERSION,
-                BROOKLYN_TEST_MORE_ENTITIES_V1_URL);
-        addCatalogItemWithTypeAsName(
-                OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY,
-                TEST_VERSION,
-                BROOKLYN_TEST_MORE_ENTITIES_V2_URL, BROOKLYN_TEST_OSGI_ENTITIES_URL);
-        
-        // test load and instantiate
-        Entity me = addItemFromCatalog( mgmt.getCatalog().getCatalogItem(OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY, TEST_VERSION) );
-        
-        assertV2MethodCall(me);
-        assertV2EffectorCall(me);
-        Assert.assertEquals(me.getPolicies().size(), 1, "Wrong number of policies: "+me.getPolicies());
-    }
-
-    @Test
-    public void testMoreEntitiesV2ThenV1GivesV1() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), BROOKLYN_TEST_MORE_ENTITIES_V1_PATH);
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), BROOKLYN_TEST_MORE_ENTITIES_V2_PATH);
-
-        addCatalogItemWithTypeAsName(
-                OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY,
-                TEST_VERSION,
-                BROOKLYN_TEST_MORE_ENTITIES_V2_URL, BROOKLYN_TEST_OSGI_ENTITIES_URL);
-        addCatalogItemWithTypeAsName(
-                OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY,
-                TEST_VERSION,
-                BROOKLYN_TEST_MORE_ENTITIES_V1_URL);
-        
-        // test load and instantiate
-        Entity me = addItemFromCatalog( mgmt.getCatalog().getCatalogItem(OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY, TEST_VERSION) );
-        /*
-         * WARNING - Weird maven-bundle-plugin and OSGi behaviour.  Some caveats:
-         * <p>
-         * (1) When "import-package" declares a version, that is the *minimum* version;
-         *     it may be that semantic versioning is applied, so 1.3.1 = [1.3.1,4.0.0);
-         *     or it may be just a minimum 1.3.1 = [1.3.1,) ... i can't find good docs
-         *     [but see http://www.christianposta.com/blog/?p=241]
-         * <p>
-         * (2) Different versions of maven-bundle-plugin do wildly different things.
-         *     * v1.4.0 attaches the version to import-package (so you get the minimum
-         *       which can cause this test to fail);
-         *     * v2.x does not seem to declare the exported package at all in import-package
-         *       (violating the so-called best practice, see
-         *       http://blog.osgi.org/2007/04/importance-of-exporting-nd-importing.html )
-         *     * v2.4.0 gives a huge list in import/export package, with semver ranges;
-         *       but the other versions seem not to list much and they do NOT have versions
-         * <p>
-         * The tests are all working with 2.5.3 but if version dependencies become any
-         * more intertwined maven-bundle-plugin will almost certainly NOT do the wrong
-         * thing because packages do not have versions. (Ironically, 1.4.0 seems the
-         * best behaved, but for the minimum/semver package version behaviour, and
-         * even that wouldn't be so bad if you're doing semver, or if you figure out
-         * how to override with a _versionpolicy tag!)
-         */
-        assertV1MethodCall(me);
-        assertV1EffectorCall(me);
-        Assert.assertEquals(me.getPolicies().size(), 0, "Wrong number of policies: "+me.getPolicies());
-    }
-
-    @Test
-    public void testUnfazedByMoreEntitiesV1AndV2AndV2EvilTwin() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), BROOKLYN_TEST_MORE_ENTITIES_V1_PATH);
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), BROOKLYN_TEST_MORE_ENTITIES_V2_PATH);
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), BROOKLYN_TEST_MORE_ENTITIES_V2_EVIL_TWIN_PATH);
-
-        addCatalogItemWithNameAndType("v1",
-                TEST_VERSION,
-                OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY,
-                BROOKLYN_TEST_MORE_ENTITIES_V1_URL);
-        addCatalogItemWithNameAndType("v2",
-                TEST_VERSION,
-                OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY,
-                BROOKLYN_TEST_MORE_ENTITIES_V2_URL, BROOKLYN_TEST_OSGI_ENTITIES_URL);
-        addCatalogItemWithNameAndType("v2-evil", 
-                TEST_VERSION,
-                OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY,
-                BROOKLYN_TEST_MORE_ENTITIES_V2_EVIL_TWIN_URL, BROOKLYN_TEST_OSGI_ENTITIES_URL);
-
-        // test osgi finding
-        
-        List<Bundle> bundles = Osgis.bundleFinder(mgmt.getOsgiManager().get().getFramework())
-            .symbolicName(OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_SYMBOLIC_NAME_FULL).findAll();
-        Assert.assertEquals(bundles.size(), 3, "Wrong list of bundles: "+bundles);
-        
-        Maybe<Bundle> preferredVersion = Osgis.bundleFinder(mgmt.getOsgiManager().get().getFramework())
-            .symbolicName(OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_SYMBOLIC_NAME_FULL).find();
-        Assert.assertTrue(preferredVersion.isPresent());
-        Assert.assertEquals(preferredVersion.get().getVersion().toString(), "0.2.0");
-        
-        Maybe<Bundle> evilVersion = Osgis.bundleFinder(mgmt.getOsgiManager().get().getFramework()).
-            preferringFromUrl(BROOKLYN_TEST_MORE_ENTITIES_V2_EVIL_TWIN_URL).find();
-        Assert.assertTrue(evilVersion.isPresent());
-        Assert.assertEquals(evilVersion.get().getVersion().toString(), "0.2.0");
-
-        // test preferredUrl vs requiredUrl
-
-        Maybe<Bundle> versionIgnoresInvalidPreferredUrl = Osgis.bundleFinder(mgmt.getOsgiManager().get().getFramework())
-            .symbolicName(OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_SYMBOLIC_NAME_FULL)
-            .version(TEST_VERSION)
-            .preferringFromUrl(BROOKLYN_TEST_MORE_ENTITIES_V2_EVIL_TWIN_URL).find();
-        Assert.assertTrue(versionIgnoresInvalidPreferredUrl.isPresent());
-        Assert.assertEquals(versionIgnoresInvalidPreferredUrl.get().getVersion().toString(), TEST_VERSION);
-
-        Maybe<Bundle> versionRespectsInvalidRequiredUrl = Osgis.bundleFinder(mgmt.getOsgiManager().get().getFramework())
-            .symbolicName(OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_SYMBOLIC_NAME_FULL)
-            .version(TEST_VERSION)
-            .requiringFromUrl(BROOKLYN_TEST_MORE_ENTITIES_V2_EVIL_TWIN_URL).find();
-        Assert.assertFalse(versionRespectsInvalidRequiredUrl.isPresent());
-
-        // test entity resolution
-        
-        Entity v2 = addItemFromCatalog( mgmt.getCatalog().getCatalogItem("v2", TEST_VERSION) );
-        assertV2MethodCall(v2);
-        assertV2EffectorCall(v2);
-        Assert.assertEquals(v2.getPolicies().size(), 1, "Wrong number of policies: "+v2.getPolicies());
-
-        Entity v2_evil = addItemFromCatalog( mgmt.getCatalog().getCatalogItem("v2-evil", TEST_VERSION) );
-        assertV2EvilTwinMethodCall(v2_evil);
-        assertV2EvilTwinEffectorCall(v2_evil);
-        Assert.assertEquals(v2_evil.getPolicies().size(), 1, "Wrong number of policies: "+v2_evil.getPolicies());
-
-        Entity v1 = addItemFromCatalog( mgmt.getCatalog().getCatalogItem("v1", TEST_VERSION) );
-        assertV1MethodCall(v1);
-        assertV1EffectorCall(v1);
-        Assert.assertEquals(v1.getPolicies().size(), 0, "Wrong number of policies: "+v1.getPolicies());
-    }
-
-    // TODO versioning (WIP until #92), install both V1 and V2 with version number, and test that both work
-        
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/test/java/brooklyn/qa/longevity/EntityCleanupLongevityTestFixture.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/qa/longevity/EntityCleanupLongevityTestFixture.java b/core/src/test/java/brooklyn/qa/longevity/EntityCleanupLongevityTestFixture.java
index f419101..85eaf3d 100644
--- a/core/src/test/java/brooklyn/qa/longevity/EntityCleanupLongevityTestFixture.java
+++ b/core/src/test/java/brooklyn/qa/longevity/EntityCleanupLongevityTestFixture.java
@@ -26,6 +26,9 @@ import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.SensorEvent;
 import org.apache.brooklyn.api.event.SensorEventListener;
 import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.core.management.internal.AbstractManagementContext;
+import org.apache.brooklyn.core.management.internal.LocalManagementContext;
+import org.apache.brooklyn.core.management.internal.ManagementContextInternal;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.apache.brooklyn.test.entity.TestEntity;
@@ -43,9 +46,6 @@ import brooklyn.internal.storage.impl.BrooklynStorageImpl;
 
 import org.apache.brooklyn.location.basic.SimulatedLocation;
 
-import brooklyn.management.internal.AbstractManagementContext;
-import brooklyn.management.internal.LocalManagementContext;
-import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.util.task.BasicExecutionManager;
 import brooklyn.util.task.TaskScheduler;
 import brooklyn.util.text.Strings;
@@ -66,7 +66,7 @@ public abstract class EntityCleanupLongevityTestFixture {
     final static long MEMORY_MARGIN_OF_ERROR = 10*1024*1024;
 
     /** Iterations might currently leave behind:
-     * <li> brooklyn.management.usage.ApplicationUsage$ApplicationEvent (one each for started/stopped/destroyed, per app)
+     * <li> org.apache.brooklyn.core.management.usage.ApplicationUsage$ApplicationEvent (one each for started/stopped/destroyed, per app)
      * <li> SingleThreadedScheduler (subscription delivery tag for the entity)
      * <p>
      * Set at 2kb per iter for now. We'd like to drop this to 0 of course!

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/test/java/brooklyn/util/task/ssh/SshTasksTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/util/task/ssh/SshTasksTest.java b/core/src/test/java/brooklyn/util/task/ssh/SshTasksTest.java
index f5e0052..578164f 100644
--- a/core/src/test/java/brooklyn/util/task/ssh/SshTasksTest.java
+++ b/core/src/test/java/brooklyn/util/task/ssh/SshTasksTest.java
@@ -23,6 +23,7 @@ import java.io.IOException;
 
 import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
+import org.apache.brooklyn.core.management.internal.LocalManagementContext;
 import org.apache.commons.io.FileUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -37,7 +38,6 @@ import brooklyn.entity.basic.Entities;
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
 
-import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.net.Urls;
 import brooklyn.util.os.Os;
 import brooklyn.util.ssh.BashCommandsIntegrationTest;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/test/java/brooklyn/util/task/system/SystemTasksTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/util/task/system/SystemTasksTest.java b/core/src/test/java/brooklyn/util/task/system/SystemTasksTest.java
index b19c389..e60310d 100644
--- a/core/src/test/java/brooklyn/util/task/system/SystemTasksTest.java
+++ b/core/src/test/java/brooklyn/util/task/system/SystemTasksTest.java
@@ -21,13 +21,13 @@ package brooklyn.util.task.system;
 import java.io.File;
 
 import org.apache.brooklyn.api.management.ManagementContext;
+import org.apache.brooklyn.core.management.internal.LocalManagementContext;
 import org.testng.Assert;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.Entities;
-import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.os.Os;
 import brooklyn.util.task.ssh.SshTasks;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/test/java/brooklyn/util/text/TemplateProcessorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/util/text/TemplateProcessorTest.java b/core/src/test/java/brooklyn/util/text/TemplateProcessorTest.java
index a9143cc..bd8ef87 100644
--- a/core/src/test/java/brooklyn/util/text/TemplateProcessorTest.java
+++ b/core/src/test/java/brooklyn/util/text/TemplateProcessorTest.java
@@ -21,6 +21,7 @@ package brooklyn.util.text;
 import static org.testng.Assert.assertEquals;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.core.management.internal.ManagementContextInternal;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.testng.Assert;
@@ -30,7 +31,6 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.event.basic.DependentConfiguration;
-import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.test.FixedLocaleTest;
 
 import com.google.common.collect.ImmutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/test/java/org/apache/brooklyn/core/management/entitlement/AcmeEntitlementManager.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/management/entitlement/AcmeEntitlementManager.java b/core/src/test/java/org/apache/brooklyn/core/management/entitlement/AcmeEntitlementManager.java
new file mode 100644
index 0000000..0d0daa5
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/management/entitlement/AcmeEntitlementManager.java
@@ -0,0 +1,52 @@
+/*
+ * 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.management.entitlement;
+
+import org.apache.brooklyn.api.management.entitlement.EntitlementClass;
+import org.apache.brooklyn.api.management.entitlement.EntitlementContext;
+import org.apache.brooklyn.api.management.entitlement.EntitlementManager;
+import org.apache.brooklyn.core.management.entitlement.Entitlements;
+import org.apache.brooklyn.core.management.entitlement.PerUserEntitlementManager;
+
+public class AcmeEntitlementManager extends PerUserEntitlementManager {
+
+    public AcmeEntitlementManager() {
+        // default mode (if no user specified) is root
+        super(Entitlements.root());
+        
+        super.addUser("admin", Entitlements.root());
+        
+        super.addUser("support", Entitlements.readOnly());
+        
+        // metrics can log in but can't really do much else
+        super.addUser("metrics", Entitlements.minimal());
+        
+        // 'navigator' defines a user with a custom entitlement manager allowing 
+        // access to see entities (in the tree) but not to do anything 
+        // or even see any sensor information on those entities
+        super.addUser("navigator", new EntitlementManager() {
+            @Override
+            public <T> boolean isEntitled(EntitlementContext context, EntitlementClass<T> entitlementClass, T entitlementClassArgument) {
+                if (Entitlements.SEE_ENTITY.equals(entitlementClass)) return true;
+                return false;
+            }
+        });
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/test/java/org/apache/brooklyn/core/management/entitlement/AcmeEntitlementManagerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/management/entitlement/AcmeEntitlementManagerTest.java b/core/src/test/java/org/apache/brooklyn/core/management/entitlement/AcmeEntitlementManagerTest.java
new file mode 100644
index 0000000..82fa5bd
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/management/entitlement/AcmeEntitlementManagerTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.management.entitlement;
+
+import java.net.URI;
+
+import org.apache.brooklyn.core.management.entitlement.Entitlements;
+import org.apache.brooklyn.core.management.entitlement.WebEntitlementContext;
+import org.apache.brooklyn.core.management.entitlement.Entitlements.EntityAndItem;
+import org.apache.brooklyn.core.management.entitlement.Entitlements.StringAndArgument;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class AcmeEntitlementManagerTest extends AcmeEntitlementManagerTestFixture {
+
+    protected void addGlobalConfig() {
+        configBag.put(Entitlements.GLOBAL_ENTITLEMENT_MANAGER, AcmeEntitlementManager.class.getName());
+    }
+
+    @Test
+    public void testOtherAuthorizedUserHasAllPermissions() {
+        checkUserHasAllPermissions("other");
+    }
+
+    @Test
+    public void testNullUserHasAllPermissions() {
+        checkUserHasAllPermissions(null);
+    }
+
+    @Test
+    public void testNavigatorHasListPermissionsOnly() {
+        setup(configBag);
+        WebEntitlementContext entitlementContext = new WebEntitlementContext("navigator", "127.0.0.1", URI.create("/X").toString(), "X");
+        Entitlements.setEntitlementContext(entitlementContext);
+        Assert.assertFalse(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.ROOT, null));
+        Assert.assertTrue(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.SEE_ENTITY, app));
+        Assert.assertFalse(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, StringAndArgument.of("any-eff", null))));
+        Assert.assertFalse(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.SEE_SENSOR, EntityAndItem.of(app, "any-sensor")));
+        // and cannot invoke methods
+        confirmEffectorEntitlement(false);
+    }
+
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/test/java/org/apache/brooklyn/core/management/entitlement/AcmeEntitlementManagerTestFixture.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/management/entitlement/AcmeEntitlementManagerTestFixture.java b/core/src/test/java/org/apache/brooklyn/core/management/entitlement/AcmeEntitlementManagerTestFixture.java
new file mode 100644
index 0000000..5689da2
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/management/entitlement/AcmeEntitlementManagerTestFixture.java
@@ -0,0 +1,158 @@
+/*
+ * 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.management.entitlement;
+
+import java.io.IOException;
+import java.net.URI;
+
+import org.apache.brooklyn.api.entity.Application;
+import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.management.ManagementContext;
+import org.apache.brooklyn.core.management.entitlement.Entitlements;
+import org.apache.brooklyn.core.management.entitlement.NotEntitledException;
+import org.apache.brooklyn.core.management.entitlement.WebEntitlementContext;
+import org.apache.brooklyn.core.management.entitlement.Entitlements.EntityAndItem;
+import org.apache.brooklyn.core.management.entitlement.Entitlements.StringAndArgument;
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+
+import brooklyn.config.BrooklynProperties;
+import brooklyn.entity.basic.ApplicationBuilder;
+import brooklyn.entity.basic.BasicApplication;
+import brooklyn.entity.basic.Entities;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.exceptions.Exceptions;
+
+public abstract class AcmeEntitlementManagerTestFixture {
+
+    protected ManagementContext mgmt;
+    protected Application app;
+    protected ConfigBag configBag;
+    
+    public void setup(ConfigBag cfg) {
+        mgmt = new LocalManagementContextForTests(BrooklynProperties.Factory.newEmpty().addFrom(cfg));
+        app = ApplicationBuilder.newManagedApp(EntitySpec.create(BasicApplication.class), mgmt);
+    }
+
+    @BeforeMethod(alwaysRun=true)
+    public void init() throws IOException {
+        Entitlements.clearEntitlementContext();
+        configBag = ConfigBag.newInstance();
+        addGlobalConfig();
+    }
+
+    protected abstract void addGlobalConfig() throws IOException;
+    
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() {
+        Entitlements.clearEntitlementContext();
+        if (app != null) Entities.destroyAll(app.getManagementContext());
+        if (mgmt != null) Entities.destroyAll(mgmt);
+        app = null;
+        mgmt = null;
+    }
+
+    @Test
+    public void testMetricsHasMinimalPermissions() {
+        checkUserHasMinimalPermissions("metrics");
+    }
+    
+    public void checkUserHasMinimalPermissions(String username) {
+        setup(configBag);
+        WebEntitlementContext entitlementContext = new WebEntitlementContext(username, "127.0.0.1", URI.create("/applications").toString(), "H");
+        Entitlements.setEntitlementContext(entitlementContext);
+        Assert.assertFalse(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.ROOT, null));
+        Assert.assertFalse(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.SEE_ENTITY, app));
+        Assert.assertFalse(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, StringAndArgument.of("any-eff", null))));
+        Assert.assertFalse(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.SEE_SENSOR, EntityAndItem.of(app, "any-sensor")));
+        // and can invoke methods
+        confirmEffectorEntitlement(false);
+    }
+
+    @Test
+    public void testSupportHasReadOnlyPermissions() {
+        checkUserHasReadOnlyPermissions("support");
+    }
+    
+    public void checkUserHasReadOnlyPermissions(String username) {
+        setup(configBag);
+        WebEntitlementContext entitlementContext = new WebEntitlementContext(username, "127.0.0.1", URI.create("/X").toString(), "B");
+        Entitlements.setEntitlementContext(entitlementContext);
+        Assert.assertFalse(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.ROOT, null));
+        Assert.assertTrue(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.SEE_ENTITY, app));
+        Assert.assertFalse(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, StringAndArgument.of("any-eff", null))));
+        Assert.assertTrue(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.SEE_SENSOR, EntityAndItem.of(app, "any-sensor")));
+        // and cannot invoke methods
+        confirmEffectorEntitlement(false);
+    }
+
+    @Test
+    public void testAdminHasAllPermissions() {
+        checkUserHasAllPermissions("admin");
+    }
+    
+    public void checkUserHasAllPermissions(String user) {
+        setup(configBag);
+        WebEntitlementContext entitlementContext = new WebEntitlementContext(user, "127.0.0.1", URI.create("/X").toString(), "A");
+        Entitlements.setEntitlementContext(entitlementContext);
+        Assert.assertTrue(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.ROOT, null));
+        Assert.assertTrue(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.SEE_ENTITY, app));
+        Assert.assertTrue(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, StringAndArgument.of("any-eff", null))));
+        Assert.assertTrue(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.SEE_SENSOR, EntityAndItem.of(app, "any-sensor")));
+        // and can invoke methods
+        confirmEffectorEntitlement(true);
+    }
+
+    protected void confirmEffectorEntitlement(boolean shouldSucceed) {
+        try {
+            ((BasicApplication)app).start(ImmutableList.<Location>of());
+            checkNoException(shouldSucceed);
+        } catch (Exception e) {
+            checkNotEntitledException(shouldSucceed, e);
+        }
+    }
+
+    private void checkNoException(boolean shouldBeEntitled) {
+        checkNotEntitledException(shouldBeEntitled, null);
+    }
+
+    private void checkNotEntitledException(boolean shouldBeEntitled, Exception e) {
+        if (e==null) {
+            if (shouldBeEntitled) return;
+            Assert.fail("entitlement should have been denied");
+        }
+        
+        Exception notEntitled = Exceptions.getFirstThrowableOfType(e, NotEntitledException.class);
+        if (notEntitled==null)
+            throw Exceptions.propagate(e);
+        if (!shouldBeEntitled) {
+            /* denied, as it should have been */ 
+            return;
+        }
+        Assert.fail("entitlement should have been granted, but was denied: "+e);
+    }
+
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/test/java/org/apache/brooklyn/core/management/entitlement/EntitlementsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/management/entitlement/EntitlementsTest.java b/core/src/test/java/org/apache/brooklyn/core/management/entitlement/EntitlementsTest.java
new file mode 100644
index 0000000..aac83f6
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/management/entitlement/EntitlementsTest.java
@@ -0,0 +1,208 @@
+/*
+ * 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.management.entitlement;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import org.apache.brooklyn.api.entity.Application;
+import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.management.ManagementContext;
+import org.apache.brooklyn.api.management.entitlement.EntitlementManager;
+import org.apache.brooklyn.core.management.entitlement.Entitlements;
+import org.apache.brooklyn.core.management.entitlement.Entitlements.EntityAndItem;
+import org.apache.brooklyn.core.management.entitlement.Entitlements.StringAndArgument;
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.config.BrooklynProperties;
+import brooklyn.entity.basic.ApplicationBuilder;
+import brooklyn.entity.basic.BasicApplication;
+import brooklyn.entity.basic.Entities;
+
+@Test
+public class EntitlementsTest {
+
+    private ManagementContext mgmt;
+    private Application app;
+
+    @BeforeMethod
+    public void setup() {
+        mgmt = new LocalManagementContextForTests(BrooklynProperties.Factory.newEmpty());
+        app = ApplicationBuilder.newManagedApp(EntitySpec.create(BasicApplication.class), mgmt);
+    }
+
+    @AfterMethod
+    public void tearDown() {
+        if (app != null) Entities.destroyAll(app.getManagementContext());
+        if (mgmt != null) Entities.destroyAll(mgmt);
+        app = null;
+        mgmt = null;
+    }
+
+    // allowing
+    public void testAllowingRoot() {
+        EntitlementManager allowSeeEntity = Entitlements.FineGrainedEntitlements.allowing(Entitlements.ROOT);
+        assertTrue(allowSeeEntity.isEntitled(null, Entitlements.ROOT, null));
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.SEE_ENTITY, null));
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.INVOKE_EFFECTOR, null));
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.SEE_SENSOR, null));
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.DEPLOY_APPLICATION, null));
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.SEE_ALL_SERVER_INFO, null));
+    }
+    public void testAllowingSeeEntity() {
+        EntitlementManager allowSeeEntity = Entitlements.FineGrainedEntitlements.allowing(Entitlements.SEE_ENTITY);
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.ROOT, null));
+        assertTrue(allowSeeEntity.isEntitled(null, Entitlements.SEE_ENTITY, null));
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.INVOKE_EFFECTOR, null));
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.SEE_SENSOR, null));
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.DEPLOY_APPLICATION, null));
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.SEE_ALL_SERVER_INFO, null));
+    }
+    public void testAllowingInvokeEffector() {
+        EntitlementManager allowSeeEntity = Entitlements.FineGrainedEntitlements.allowing(Entitlements.INVOKE_EFFECTOR);
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.ROOT, null));
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.SEE_ENTITY, null));
+        assertTrue(allowSeeEntity.isEntitled(null, Entitlements.INVOKE_EFFECTOR, null));
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.SEE_SENSOR, null));
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.DEPLOY_APPLICATION, null));
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.SEE_ALL_SERVER_INFO, null));
+    }
+    public void testAllowingSeeSensor() {
+        EntitlementManager allowSeeEntity = Entitlements.FineGrainedEntitlements.allowing(Entitlements.SEE_SENSOR);
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.ROOT, null));
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.SEE_ENTITY, null));
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.INVOKE_EFFECTOR, null));
+        assertTrue(allowSeeEntity.isEntitled(null, Entitlements.SEE_SENSOR, null));
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.DEPLOY_APPLICATION, null));
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.SEE_ALL_SERVER_INFO, null));
+    }
+    public void testAllowingDeployApplication() {
+        EntitlementManager allowSeeEntity = Entitlements.FineGrainedEntitlements.allowing(Entitlements.DEPLOY_APPLICATION);
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.ROOT, null));
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.SEE_ENTITY, null));
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.INVOKE_EFFECTOR, null));
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.SEE_SENSOR, null));
+        assertTrue(allowSeeEntity.isEntitled(null, Entitlements.DEPLOY_APPLICATION, null));
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.SEE_ALL_SERVER_INFO, null));
+    }
+    public void testAllowingSeeAllServerInfo() {
+        EntitlementManager allowSeeEntity = Entitlements.FineGrainedEntitlements.allowing(Entitlements.SEE_ALL_SERVER_INFO);
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.ROOT, null));
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.SEE_ENTITY, null));
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.INVOKE_EFFECTOR, null));
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.SEE_SENSOR, null));
+        assertFalse(allowSeeEntity.isEntitled(null, Entitlements.DEPLOY_APPLICATION, null));
+        assertTrue(allowSeeEntity.isEntitled(null, Entitlements.SEE_ALL_SERVER_INFO, null));
+    }
+
+    // nonSecret
+    public void testSeeNonSecretSensors() {
+        EntitlementManager seeNonSecretSensors = Entitlements.FineGrainedEntitlements.seeNonSecretSensors();
+        assertFalse(seeNonSecretSensors.isEntitled(null, Entitlements.SEE_SENSOR, Entitlements.EntityAndItem.of(app, "password")));
+        assertTrue(seeNonSecretSensors.isEntitled(null, Entitlements.SEE_SENSOR, Entitlements.EntityAndItem.of(app, "any-sensor")));
+    }
+
+    // allOf
+    public void testAllOfWithSeeEntityAndSeeSensors() {
+        EntitlementManager allOf = Entitlements.FineGrainedEntitlements.allOf(
+                Entitlements.FineGrainedEntitlements.allowing(Entitlements.SEE_ENTITY),
+                Entitlements.FineGrainedEntitlements.allowing(Entitlements.SEE_SENSOR));
+        assertFalse(allOf.isEntitled(null, Entitlements.ROOT, null));
+        assertTrue(allOf.isEntitled(null, Entitlements.SEE_ENTITY, null));
+        assertFalse(allOf.isEntitled(null, Entitlements.INVOKE_EFFECTOR, null));
+        assertTrue(allOf.isEntitled(null, Entitlements.SEE_SENSOR, null));
+        assertFalse(allOf.isEntitled(null, Entitlements.DEPLOY_APPLICATION, null));
+        assertFalse(allOf.isEntitled(null, Entitlements.SEE_ALL_SERVER_INFO, null));
+    }
+
+    // anyOf
+    public void testAnyOfWithSeeEntityAndSeeSensors() {
+        EntitlementManager anyOf = Entitlements.FineGrainedEntitlements.anyOf(
+                Entitlements.FineGrainedEntitlements.allowing(Entitlements.SEE_ENTITY),
+                Entitlements.FineGrainedEntitlements.allowing(Entitlements.SEE_SENSOR));
+        assertFalse(anyOf.isEntitled(null, Entitlements.ROOT, null));
+        assertTrue(anyOf.isEntitled(null, Entitlements.SEE_ENTITY, null));
+        assertFalse(anyOf.isEntitled(null, Entitlements.INVOKE_EFFECTOR, null));
+        assertTrue(anyOf.isEntitled(null, Entitlements.SEE_SENSOR, null));
+        assertFalse(anyOf.isEntitled(null, Entitlements.DEPLOY_APPLICATION, null));
+        assertFalse(anyOf.isEntitled(null, Entitlements.SEE_ALL_SERVER_INFO, null));
+    }
+
+    // root
+    public void testGlobalRootEntitlement() {
+        EntitlementManager root = Entitlements.root();
+        assertTrue(root.isEntitled(null, Entitlements.ROOT, null));
+        assertTrue(root.isEntitled(null, Entitlements.SEE_ENTITY, null));
+        assertTrue(root.isEntitled(null, Entitlements.INVOKE_EFFECTOR, null));
+        assertTrue(root.isEntitled(null, Entitlements.SEE_SENSOR, null));
+        assertTrue(root.isEntitled(null, Entitlements.DEPLOY_APPLICATION, null));
+        assertTrue(root.isEntitled(null, Entitlements.SEE_ALL_SERVER_INFO, null));
+    }
+    public void testAppSpecificRootEntitlement() {
+        EntitlementManager root = Entitlements.root();
+        assertTrue(root.isEntitled(null, Entitlements.SEE_ENTITY, app));
+        assertTrue(root.isEntitled(null, Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, StringAndArgument.of("any-eff", null))));
+        assertTrue(root.isEntitled(null, Entitlements.SEE_SENSOR, Entitlements.EntityAndItem.of(app, "any-sensor")));
+        assertTrue(root.isEntitled(null, Entitlements.SEE_SENSOR, Entitlements.EntityAndItem.of(app, "password")));
+        assertTrue(root.isEntitled(null, Entitlements.DEPLOY_APPLICATION, Entitlements.EntityAndItem.of(app, null)));
+        assertTrue(root.isEntitled(null, Entitlements.SEE_ALL_SERVER_INFO, null));
+    }
+
+    // minimal
+    public void testGlobalMinimalEntitlement() {
+        EntitlementManager minimal = Entitlements.minimal();
+        assertFalse(minimal.isEntitled(null, Entitlements.ROOT, null));
+        assertFalse(minimal.isEntitled(null, Entitlements.SEE_ENTITY, null));
+        assertFalse(minimal.isEntitled(null, Entitlements.INVOKE_EFFECTOR, null));
+        assertFalse(minimal.isEntitled(null, Entitlements.SEE_SENSOR, null));
+        assertFalse(minimal.isEntitled(null, Entitlements.DEPLOY_APPLICATION, null));
+        assertFalse(minimal.isEntitled(null, Entitlements.SEE_ALL_SERVER_INFO, null));
+    }
+    public void testAppSpecificMinimalEntitlement() {
+        EntitlementManager minimal = Entitlements.minimal();
+        assertFalse(minimal.isEntitled(null, Entitlements.SEE_ENTITY, app));
+        assertFalse(minimal.isEntitled(null, Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, StringAndArgument.of("any-eff", null))));
+        assertFalse(minimal.isEntitled(null, Entitlements.SEE_SENSOR, Entitlements.EntityAndItem.of(app, "any-sensor")));
+        assertFalse(minimal.isEntitled(null, Entitlements.SEE_SENSOR, Entitlements.EntityAndItem.of(app, "password")));
+        assertFalse(minimal.isEntitled(null, Entitlements.DEPLOY_APPLICATION, Entitlements.EntityAndItem.of(app, null)));
+        assertFalse(minimal.isEntitled(null, Entitlements.SEE_ALL_SERVER_INFO, null));
+    }
+
+    // readOnly
+    public void testGlobalReadOnlyEntitlement() {
+        EntitlementManager readOnly = Entitlements.readOnly();
+        assertFalse(readOnly.isEntitled(null, Entitlements.ROOT, null));
+        assertTrue(readOnly.isEntitled(null, Entitlements.SEE_ENTITY, null));
+        assertFalse(readOnly.isEntitled(null, Entitlements.INVOKE_EFFECTOR, null));
+        assertFalse(readOnly.isEntitled(null, Entitlements.SEE_SENSOR, null));
+        assertFalse(readOnly.isEntitled(null, Entitlements.DEPLOY_APPLICATION, null));
+        assertFalse(readOnly.isEntitled(null, Entitlements.SEE_ALL_SERVER_INFO, null));
+    }
+    public void testAppSpecificReadOnlyEntitlement() {
+        EntitlementManager readOnly = Entitlements.readOnly();
+        assertTrue(readOnly.isEntitled(null, Entitlements.SEE_ENTITY, app));
+        assertFalse(readOnly.isEntitled(null, Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, StringAndArgument.of("any-eff", null))));
+        assertTrue(readOnly.isEntitled(null, Entitlements.SEE_SENSOR, Entitlements.EntityAndItem.of(app, "any-sensor")));
+        assertFalse(readOnly.isEntitled(null, Entitlements.SEE_SENSOR, Entitlements.EntityAndItem.of(app, "password")));
+        assertFalse(readOnly.isEntitled(null, Entitlements.DEPLOY_APPLICATION, Entitlements.EntityAndItem.of(app, null)));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/test/java/org/apache/brooklyn/core/management/entitlement/EntityEntitlementTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/management/entitlement/EntityEntitlementTest.java b/core/src/test/java/org/apache/brooklyn/core/management/entitlement/EntityEntitlementTest.java
new file mode 100644
index 0000000..bb25740
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/management/entitlement/EntityEntitlementTest.java
@@ -0,0 +1,185 @@
+/*
+ * 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.management.entitlement;
+
+import org.apache.brooklyn.api.entity.Application;
+import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.management.ManagementContext;
+import org.apache.brooklyn.core.management.entitlement.Entitlements;
+import org.apache.brooklyn.core.management.entitlement.NotEntitledException;
+import org.apache.brooklyn.core.management.entitlement.Entitlements.EntityAndItem;
+import org.apache.brooklyn.core.management.entitlement.Entitlements.StringAndArgument;
+import org.apache.brooklyn.core.management.internal.LocalManagementContext;
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+
+import brooklyn.config.BrooklynProperties;
+import brooklyn.entity.basic.ApplicationBuilder;
+import brooklyn.entity.basic.BasicApplication;
+import brooklyn.entity.basic.Entities;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.exceptions.Exceptions;
+
+public class EntityEntitlementTest {
+
+    private static final Logger log = LoggerFactory.getLogger(EntityEntitlementTest.class);
+    
+    ManagementContext mgmt;
+    Application app;
+    
+    public void setup(ConfigBag cfg) {
+        mgmt = new LocalManagementContextForTests(BrooklynProperties.Factory.newEmpty().addFrom(cfg));
+        app = ApplicationBuilder.newManagedApp(EntitySpec.create(BasicApplication.class), mgmt);
+    }
+    
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() {
+        if (app != null) Entities.destroyAll(app.getManagementContext());
+        if (mgmt != null) Entities.destroyAll(mgmt);
+        app = null;
+        mgmt = null;
+    }
+
+    @Test
+    public void testDefaultRootAllows() {
+        setup(ConfigBag.newInstance());
+        // default "root" access allows ROOT permission, and invoke effector, etc
+        Assert.assertTrue(mgmt.getEntitlementManager().isEntitled(null, Entitlements.ROOT, null));
+        Assert.assertTrue(mgmt.getEntitlementManager().isEntitled(null, Entitlements.SEE_ENTITY, app));
+        Assert.assertTrue(mgmt.getEntitlementManager().isEntitled(null, Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, StringAndArgument.of("any-eff", null))));
+        Assert.assertTrue(mgmt.getEntitlementManager().isEntitled(null, Entitlements.SEE_SENSOR, EntityAndItem.of(app, "any-sensor")));
+        // and can invoke methods, without any user/login registered
+        confirmEffectorEntitlement(true);
+        confirmSensorEntitlement(true);
+    }
+
+    @Test
+    public void testExplicitRootAllows() {
+        setup(ConfigBag.newInstance().configure(Entitlements.GLOBAL_ENTITLEMENT_MANAGER, "root"));
+        
+        Assert.assertTrue(mgmt.getEntitlementManager().isEntitled(null, Entitlements.ROOT, null));
+        Assert.assertTrue(mgmt.getEntitlementManager().isEntitled(null, Entitlements.SEE_ENTITY, app));
+        Assert.assertTrue(mgmt.getEntitlementManager().isEntitled(null, Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, StringAndArgument.of("any-eff", null))));
+        Assert.assertTrue(mgmt.getEntitlementManager().isEntitled(null, Entitlements.SEE_SENSOR, EntityAndItem.of(app, "any-sensor")));
+        
+        confirmEffectorEntitlement(true);
+        confirmSensorEntitlement(true);
+    }
+
+    @Test
+    public void testReadOnlyThrowsNotEntitled() {
+        try {
+            setup(ConfigBag.newInstance().configure(Entitlements.GLOBAL_ENTITLEMENT_MANAGER, "readonly"));
+            // eventually above call will fail in app creation, but for now the call below falls
+            ((BasicApplication)app).start(ImmutableList.<Location>of());
+            tearDown();
+            
+            Assert.fail("something should have been disallowed");
+        } catch (Exception e) {
+            checkNotEntitledException(e);
+        } finally {
+            app = null;
+            if (mgmt!=null) ((LocalManagementContext)mgmt).terminate();
+            mgmt = null;
+        }
+    }
+    
+    @Test(enabled=false)
+    // this test (and minimal below) currently work fine until tearDown, 
+    // but then of course they don't have entitlement to call 'stop';
+    // (as more entitlement checks are added app creation will fail).
+    // 
+    // TODO these tests should set up a user with the permission,
+    // e.g. so system has root, but 'bob' has read-only, then we can test read-only;
+    // TODO rest api tests, as some of the permissions will only be enforced at REST level
+    public void testReadOnlyAllowsSome() {
+        setup(ConfigBag.newInstance().configure(Entitlements.GLOBAL_ENTITLEMENT_MANAGER, "readonly"));
+        
+        Assert.assertFalse(mgmt.getEntitlementManager().isEntitled(null, Entitlements.ROOT, null));
+        Assert.assertTrue(mgmt.getEntitlementManager().isEntitled(null, Entitlements.SEE_ENTITY, app));
+        Assert.assertFalse(mgmt.getEntitlementManager().isEntitled(null, Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, StringAndArgument.of("any-eff", null))));
+        Assert.assertTrue(mgmt.getEntitlementManager().isEntitled(null, Entitlements.SEE_SENSOR, EntityAndItem.of(app, "any-sensor")));
+        
+        confirmEffectorEntitlement(false);
+        confirmSensorEntitlement(true);
+    }
+    
+    @Test(enabled=false)
+    public void testMinimalDisallows() {
+        setup(ConfigBag.newInstance().configure(Entitlements.GLOBAL_ENTITLEMENT_MANAGER, "minimal"));
+        
+        Assert.assertFalse(mgmt.getEntitlementManager().isEntitled(null, Entitlements.ROOT, null));
+        Assert.assertFalse(mgmt.getEntitlementManager().isEntitled(null, Entitlements.SEE_ENTITY, app));
+        Assert.assertFalse(mgmt.getEntitlementManager().isEntitled(null, Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, StringAndArgument.of("any-eff", null))));
+        Assert.assertFalse(mgmt.getEntitlementManager().isEntitled(null, Entitlements.SEE_SENSOR, EntityAndItem.of(app, "any-sensor")));
+        
+        confirmEffectorEntitlement(false);
+        confirmSensorEntitlement(false);
+    }
+    
+    protected void confirmSensorEntitlement(boolean shouldSucceed) {
+        // TODO... based on above
+        // (though maybe we should test against REST API classes rather than lower level programmatic?
+        // TBC...)
+        log.warn("confirmSensorEntitlement still required!");
+    }
+
+    // TODO specific users tests
+    
+    protected void confirmEffectorEntitlement(boolean shouldSucceed) {
+        try {
+            ((BasicApplication)app).start(ImmutableList.<Location>of());
+            checkNoException(shouldSucceed);
+        } catch (Exception e) {
+            checkNotEntitledException(shouldSucceed, e);
+        }
+    }
+
+    private void checkNoException(boolean shouldBeEntitled) {
+        checkNotEntitledException(shouldBeEntitled, null);
+    }
+
+    private void checkNotEntitledException(Exception e) {
+        checkNotEntitledException(false, e);
+    }
+
+    private void checkNotEntitledException(boolean shouldBeEntitled, Exception e) {
+        if (e==null) {
+            if (shouldBeEntitled) return;
+            Assert.fail("entitlement should have been denied");
+        }
+        
+        Exception notEntitled = Exceptions.getFirstThrowableOfType(e, NotEntitledException.class);
+        if (notEntitled==null)
+            throw Exceptions.propagate(e);
+        if (!shouldBeEntitled) {
+            /* denied, as it should have been */ 
+            return;
+        }
+        Assert.fail("entitlement should have been granted, but was denied: "+e);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/test/java/org/apache/brooklyn/core/management/entitlement/PerUserEntitlementManagerPropertiesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/management/entitlement/PerUserEntitlementManagerPropertiesTest.java b/core/src/test/java/org/apache/brooklyn/core/management/entitlement/PerUserEntitlementManagerPropertiesTest.java
new file mode 100644
index 0000000..f420019
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/management/entitlement/PerUserEntitlementManagerPropertiesTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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.management.entitlement;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.Properties;
+
+import org.testng.annotations.Test;
+
+
+public class PerUserEntitlementManagerPropertiesTest extends AcmeEntitlementManagerTestFixture {
+
+    protected void addGlobalConfig() throws IOException {
+        Properties moreProps = new Properties();
+        moreProps.load(new StringReader(
+            "brooklyn.entitlements.global=org.apache.brooklyn.core.management.entitlement.PerUserEntitlementManager\n"
+                + "brooklyn.entitlements.perUser.admin=root\n"
+                + "brooklyn.entitlements.perUser.support=readonly\n"
+                + "brooklyn.entitlements.perUser.metrics=minimal"));
+        configBag.putAll(moreProps);
+    }
+    
+    @Test
+    public void testOtherAuthorizedUserHasMinimalPermissions() {
+        checkUserHasMinimalPermissions("other");
+    }
+
+    @Test
+    public void testNullUserHasAllPermissions() {
+        checkUserHasAllPermissions(null);
+    }
+
+
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/test/java/org/apache/brooklyn/core/management/ha/HighAvailabilityManagerFileBasedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/management/ha/HighAvailabilityManagerFileBasedTest.java b/core/src/test/java/org/apache/brooklyn/core/management/ha/HighAvailabilityManagerFileBasedTest.java
new file mode 100644
index 0000000..99640b7
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/management/ha/HighAvailabilityManagerFileBasedTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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.management.ha;
+
+import java.io.File;
+
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.rebind.persister.FileBasedObjectStore;
+import brooklyn.util.os.Os;
+
+@Test
+public class HighAvailabilityManagerFileBasedTest extends HighAvailabilityManagerTestFixture {
+
+    private File dir;
+
+    protected FileBasedObjectStore newPersistenceObjectStore() {
+        if (dir!=null)
+            throw new IllegalStateException("Test does not support multiple object stores");
+        dir = Os.newTempDir(getClass());
+        return new FileBasedObjectStore(dir);
+    }
+
+    @Override
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        super.tearDown();
+        dir = Os.deleteRecursively(dir).asNullOrThrowing();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/test/java/org/apache/brooklyn/core/management/ha/HighAvailabilityManagerInMemoryIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/management/ha/HighAvailabilityManagerInMemoryIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/core/management/ha/HighAvailabilityManagerInMemoryIntegrationTest.java
new file mode 100644
index 0000000..4b5a5cf
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/management/ha/HighAvailabilityManagerInMemoryIntegrationTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.management.ha;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.rebind.persister.InMemoryObjectStore;
+import brooklyn.entity.rebind.persister.PersistenceObjectStore;
+import brooklyn.util.time.Duration;
+import brooklyn.util.time.Time;
+
+import com.google.common.base.Ticker;
+
+@Test(groups="Integration")
+public class HighAvailabilityManagerInMemoryIntegrationTest extends HighAvailabilityManagerTestFixture {
+
+    private static final Logger log = LoggerFactory.getLogger(HighAvailabilityManagerInMemoryIntegrationTest.class);
+    
+    @Override
+    protected PersistenceObjectStore newPersistenceObjectStore() {
+        return new InMemoryObjectStore();
+    }
+
+    @Override
+    protected Duration getPollPeriod() {
+        return Duration.millis(100);
+    }
+    
+    @Override
+    protected long tickerAdvance(Duration duration) {
+        log.info("sleeping for "+duration);
+        // actually sleep, in order to advance the local time ticker
+        Time.sleep(duration);
+        return super.tickerAdvance(duration);
+    }
+
+    @Override
+    protected Ticker getRemoteTicker() {
+        // use real times
+        return null;
+    }
+
+    @Override
+    @Test(groups="Integration", enabled=false, invocationCount=50) 
+    public void testGetManagementPlaneStatusManyTimes() throws Exception {
+    }
+
+    @Test(groups="Integration")
+    @Override
+    public void testGetManagementPlaneStatus() throws Exception {
+        super.testGetManagementPlaneStatus();
+    }
+    
+    @Test(groups="Integration")
+    @Override
+    public void testDoesNotPromoteIfMasterTimeoutNotExpired() throws Exception {
+        super.testDoesNotPromoteIfMasterTimeoutNotExpired();
+    }
+    
+    @Test(groups="Integration")
+    @Override
+    public void testGetManagementPlaneSyncStateDoesNotThrowNpeBeforePersisterSet() throws Exception {
+        super.testGetManagementPlaneSyncStateDoesNotThrowNpeBeforePersisterSet();
+    }
+    
+    @Test(groups="Integration")
+    @Override
+    public void testGetManagementPlaneSyncStateInfersTimedOutNodeAsFailed() throws Exception {
+        super.testGetManagementPlaneSyncStateInfersTimedOutNodeAsFailed();
+    }
+    
+    @Test(groups="Integration")
+    @Override
+    public void testPromotes() throws Exception {
+        super.testPromotes();
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/test/java/org/apache/brooklyn/core/management/ha/HighAvailabilityManagerInMemoryTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/management/ha/HighAvailabilityManagerInMemoryTest.java b/core/src/test/java/org/apache/brooklyn/core/management/ha/HighAvailabilityManagerInMemoryTest.java
new file mode 100644
index 0000000..6ae9dfb
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/management/ha/HighAvailabilityManagerInMemoryTest.java
@@ -0,0 +1,145 @@
+/*
+ * 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.management.ha;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
+import org.apache.brooklyn.api.management.ha.HighAvailabilityMode;
+import org.apache.brooklyn.core.management.ha.HighAvailabilityManagerImpl;
+import org.apache.brooklyn.core.management.internal.LocalManagementContext;
+import org.apache.brooklyn.test.entity.TestApplication;
+import org.apache.brooklyn.test.entity.TestEntity;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.basic.EntityInternal;
+import brooklyn.entity.rebind.persister.InMemoryObjectStore;
+import brooklyn.entity.rebind.persister.PersistenceObjectStore;
+
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+
+import brooklyn.util.collections.MutableList;
+
+import com.google.common.collect.Iterables;
+
+@Test
+public class HighAvailabilityManagerInMemoryTest extends HighAvailabilityManagerTestFixture {
+
+    private static final Logger log = LoggerFactory.getLogger(HighAvailabilityManagerInMemoryTest.class);
+    
+    protected PersistenceObjectStore newPersistenceObjectStore() {
+        return new InMemoryObjectStore();
+    }
+    
+    public void testGetManagementPlaneStatus() throws Exception {
+        super.testGetManagementPlaneStatus();
+    }
+
+    // extra test that promoteToMaster doesn't interfere with what is managed
+    public void testLocationsStillManagedCorrectlyAfterDoublePromotion() throws NoMachinesAvailableException {
+        HighAvailabilityManagerImpl ha = (HighAvailabilityManagerImpl) managementContext.getHighAvailabilityManager();
+        ha.start(HighAvailabilityMode.MASTER);
+        
+        TestApplication app = TestApplication.Factory.newManagedInstanceForTests(managementContext);
+        
+        LocalhostMachineProvisioningLocation l = app.newLocalhostProvisioningLocation();
+        l.setConfig(TestEntity.CONF_NAME, "sample1");
+        Assert.assertEquals(l.getConfig(TestEntity.CONF_NAME), "sample1");
+        
+        SshMachineLocation l2 = l.obtain();
+        Assert.assertEquals(l2.getConfig(TestEntity.CONF_NAME), "sample1");
+        Assert.assertNotNull(l2.getParent(), "Parent not set after dodgy promoteToMaster");
+        Assert.assertEquals(l2.getParent().getConfig(TestEntity.CONF_NAME), "sample1");
+
+        TestEntity entity = app.createAndManageChild(EntitySpec.create(TestEntity.class).location(l).location(l2));
+        log.info("Entities managed are: "+managementContext.getEntityManager().getEntities());
+        Collection<Location> le = entity.getLocations();
+        log.info("Locs at entity are: "+le);
+        Collection<Location> lm = managementContext.getLocationManager().getLocations();
+        log.info("Locs managed are: "+lm);
+        log.info("            objs: "+identities(lm));
+        Assert.assertNotNull(entity.getManagementSupport().getManagementContext());
+        Assert.assertNotNull( ((EntityInternal)app.getChildren().iterator().next()).getManagementSupport().getManagementContext());
+        Assert.assertTrue( ((EntityInternal)app.getChildren().iterator().next()).getManagementSupport().isDeployed());
+        checkEntitiesHealthy(app, entity);
+        
+        managementContext.getRebindManager().forcePersistNow(true, null);
+        log.info("Test deliberately doing unnecessary extra promoteToMaster");
+        ha.promoteToMaster();
+        
+        log.info("Entities managed are: "+managementContext.getEntityManager().getEntities());
+        Collection<Location> lle = entity.getLocations();
+        log.info("Locs at entity(old) are: "+lle);
+        log.info("                   objs: "+identities(lle));
+        // check entities -- the initial-full promotion previously re-created items, 
+        // and plugged them in as children, but only managed the roots
+        checkEntitiesHealthy(app, entity);
+        
+        // assert what's in the location manager is accurate
+        Collection<Location> llmm = managementContext.getLocationManager().getLocations();
+        log.info("Locs managed are: "+llmm);
+        log.info("            objs: "+identities(llmm));
+        Assert.assertEquals(llmm, lm);
+        SshMachineLocation ll2a = Iterables.getOnlyElement(Iterables.filter(llmm, SshMachineLocation.class));
+        Assert.assertEquals(ll2a.getConfig(TestEntity.CONF_NAME), "sample1");
+        Assert.assertNotNull(ll2a.getParent(), "Parent not set after dodgy promoteToMaster");
+        Assert.assertEquals(ll2a.getParent().getConfig(TestEntity.CONF_NAME), "sample1");
+        
+        // and what's in the location manager is accurate
+        Entity ee = (Entity)managementContext.lookup(entity.getId());
+        Collection<Location> llee = ee.getLocations();
+        log.info("Locs at entity(lookup) are: "+llee);
+        log.info("                      objs: "+identities(llee));
+        SshMachineLocation ll2b = Iterables.getOnlyElement(Iterables.filter(llee, SshMachineLocation.class));
+        Assert.assertEquals(ll2b.getConfig(TestEntity.CONF_NAME), "sample1");
+        Assert.assertNotNull(ll2b.getParent(), "Parent not set after dodgy promoteToMaster");
+        Assert.assertEquals(ll2b.getParent().getConfig(TestEntity.CONF_NAME), "sample1");
+    }
+
+    private void checkEntitiesHealthy(TestApplication app, TestEntity entity) {
+        Assert.assertNotNull(app.getManagementSupport().getManagementContext());
+        Assert.assertTrue( app.getManagementSupport().getManagementContext().isRunning() );
+        
+        Assert.assertNotNull(entity.getManagementSupport().getManagementContext());
+        Assert.assertNotNull( ((EntityInternal)app.getChildren().iterator().next()).getManagementSupport().getManagementContext() );
+        Assert.assertTrue( ((EntityInternal)app.getChildren().iterator().next()).getManagementSupport().isDeployed());
+        Assert.assertTrue( ((EntityInternal)app.getChildren().iterator().next()).getManagementSupport().getManagementContext() instanceof LocalManagementContext );
+    }
+
+    @Test(groups="Integration", invocationCount=50)
+    public void testLocationsStillManagedCorrectlyAfterDoublePromotionManyTimes() throws NoMachinesAvailableException {
+        testLocationsStillManagedCorrectlyAfterDoublePromotion();
+    }
+    
+    private List<String> identities(Collection<?> objs) {
+        List<String> result = MutableList.of();
+        for (Object obj: objs)
+            result.add(Integer.toHexString(System.identityHashCode(obj)));
+        return result;
+    }
+    
+}


Mime
View raw message