Repository: incubator-brooklyn
Updated Branches:
  refs/heads/master b92d03925 -> 26c6542ce


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/32cf5dea/usage/launcher/src/test/java/brooklyn/launcher/BrooklynLauncherRebindTestFixture.java
----------------------------------------------------------------------
diff --git 
a/usage/launcher/src/test/java/brooklyn/launcher/BrooklynLauncherRebindTestFixture.java
 
b/usage/launcher/src/test/java/brooklyn/launcher/BrooklynLauncherRebindTestFixture.java
new file mode 100644
index 0000000..a1add01
--- /dev/null
+++ 
b/usage/launcher/src/test/java/brooklyn/launcher/BrooklynLauncherRebindTestFixture.java
@@ -0,0 +1,235 @@
+package brooklyn.launcher;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.config.BrooklynProperties;
+import brooklyn.config.BrooklynServerConfig;
+import brooklyn.entity.Application;
+import brooklyn.entity.basic.EntityPredicates;
+import brooklyn.entity.basic.StartableApplication;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.entity.rebind.persister.BrooklynMementoPersisterToObjectStore;
+import brooklyn.entity.rebind.persister.PersistMode;
+import brooklyn.entity.rebind.persister.PersistenceObjectStore;
+import brooklyn.location.Location;
+import brooklyn.management.ManagementContext;
+import brooklyn.test.Asserts;
+import brooklyn.test.entity.LocalManagementContextForTests;
+import brooklyn.test.entity.TestApplication;
+import brooklyn.util.collections.MutableList;
+import brooklyn.util.exceptions.FatalConfigurationRuntimeException;
+import brooklyn.util.time.Duration;
+
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+
+public abstract class BrooklynLauncherRebindTestFixture {
+
+    @SuppressWarnings("unused")
+    private static final Logger log = 
LoggerFactory.getLogger(BrooklynLauncherRebindTestFixture.class);
+    
+    protected String persistenceDir;
+    protected String persistenceLocationSpec;
+    protected List<BrooklynLauncher> launchers = MutableList.of();
+    
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        persistenceDir = newTempPersistenceContainerName();
+    }
+    
+    protected abstract String newTempPersistenceContainerName();
+
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        for (BrooklynLauncher l: launchers) {
+            l.terminate();
+            PersistenceObjectStore store = 
getPersistenceStore(l.getServerDetails().getManagementContext());
+            if (store!=null) store.deleteCompletely();
+        }
+    }
+
+    protected BrooklynLauncher newLauncherBase() {
+        BrooklynLauncher l = BrooklynLauncher.newInstance()
+            .webconsole(false);
+        launchers.add(l);
+        return l;
+    }
+    protected BrooklynLauncher newLauncherDefault(PersistMode mode) {
+        return newLauncherBase()
+                .managementContext(newManagementContextForTests(null))
+                .persistMode(mode)
+                .persistenceDir(persistenceDir)
+                .persistPeriod(Duration.millis(10));
+    }
+    protected LocalManagementContextForTests 
newManagementContextForTests(BrooklynProperties props) {
+        if (props==null)
+            return new LocalManagementContextForTests();
+        else
+            return new LocalManagementContextForTests(props);
+    }
+
+    protected ManagementContext lastMgmt() {
+        return 
Iterables.getLast(launchers).getServerDetails().getManagementContext();
+    }
+    
+    @Test
+    public void testRebindsToExistingApp() throws Exception {
+        populatePersistenceDir(persistenceDir, 
EntitySpec.create(TestApplication.class).displayName("myorig"));
+        
+        // Rebind to the app we just started last time
+        
+        newLauncherDefault(PersistMode.REBIND).start();
+        
+        assertOnlyApp(lastMgmt(), TestApplication.class);
+        assertNotNull(Iterables.find(lastMgmt().getApplications(), 
EntityPredicates.displayNameEqualTo("myorig"), null), 
"apps="+lastMgmt().getApplications());
+    }
+
+    @Test
+    public void testRebindCanAddNewApps() throws Exception {
+        populatePersistenceDir(persistenceDir, 
EntitySpec.create(TestApplication.class).displayName("myorig"));
+        
+        // Rebind to the app we started last time
+        newLauncherDefault(PersistMode.REBIND)
+                
.application(EntitySpec.create(TestApplication.class).displayName("mynew"))
+                .start();
+        
+        // New app was added, and orig app was rebound
+        assertEquals(lastMgmt().getApplications().size(), 2, 
"apps="+lastMgmt().getApplications());
+        assertNotNull(Iterables.find(lastMgmt().getApplications(), 
EntityPredicates.displayNameEqualTo("mynew"), null), 
"apps="+lastMgmt().getApplications());
+
+        // And subsequently can create new apps
+        StartableApplication app3 = lastMgmt().getEntityManager().createEntity(
+                
EntitySpec.create(TestApplication.class).displayName("mynew2"));
+        app3.start(ImmutableList.<Location>of());
+    }
+
+    @Test
+    public void testAutoRebindsToExistingApp() throws Exception {
+        EntitySpec<TestApplication> appSpec = 
EntitySpec.create(TestApplication.class);
+        populatePersistenceDir(persistenceDir, appSpec);
+        
+        // Auto will rebind if the dir exists
+        newLauncherDefault(PersistMode.AUTO).start();
+        
+        assertOnlyApp(lastMgmt(), TestApplication.class);
+    }
+
+    @Test
+    public void testCleanDoesNotRebindToExistingApp() throws Exception {
+        EntitySpec<TestApplication> appSpec = 
EntitySpec.create(TestApplication.class);
+        populatePersistenceDir(persistenceDir, appSpec);
+        
+        // Auto will rebind if the dir exists
+        newLauncherDefault(PersistMode.CLEAN).start();
+        
+        assertTrue(lastMgmt().getApplications().isEmpty(), 
"apps="+lastMgmt().getApplications());
+    }
+
+    @Test
+    public void testAutoRebindCreatesNewIfEmptyDir() throws Exception {
+        // Auto will rebind if the dir exists
+        newLauncherDefault(PersistMode.AUTO)
+                .application(EntitySpec.create(TestApplication.class))
+                .start();
+        
+        assertOnlyApp(lastMgmt(), TestApplication.class);
+        assertMementoContainerNonEmptyForTypeEventually("entities");
+    }
+
+    @Test
+    public void testRebindRespectsPersistenceDirSetInProperties() throws 
Exception {
+        String persistenceDir2 = newTempPersistenceContainerName();
+        
+        BrooklynProperties brooklynProperties = 
BrooklynProperties.Factory.newDefault();
+        brooklynProperties.put(BrooklynServerConfig.PERSISTENCE_DIR, 
persistenceDir2);
+        LocalManagementContextForTests mgmt = 
newManagementContextForTests(brooklynProperties);
+        
+        // Rebind to the app we started last time
+        newLauncherBase()
+                .persistMode(PersistMode.AUTO)
+                .persistPeriod(Duration.millis(10))
+                .managementContext(mgmt)
+                .start();
+        
+        checkPersistenceContainerNameIs(persistenceDir2);
+    }
+
+    // assumes default persistence dir is rebindable
+    @Test(groups="Integration")
+    public void testRebindRespectsDefaultPersistenceDir() throws Exception {
+        newLauncherDefault(PersistMode.AUTO)
+                .persistenceDir((String)null)
+                .start();
+        
+        checkPersistenceContainerNameIsDefault();
+    }
+    
+    protected abstract void checkPersistenceContainerNameIsDefault();
+    protected abstract void checkPersistenceContainerNameIs(String expected);
+
+    @Test
+    public void testPersistenceFailsIfNoDir() throws Exception {
+        runRebindFails(PersistMode.REBIND, badContainerName(), "does not 
exist");
+    }
+
+    protected abstract String badContainerName();
+
+    @Test
+    public void testExplicitRebindFailsIfEmpty() throws Exception {
+        runRebindFails(PersistMode.REBIND, persistenceDir, "directory is 
empty");
+    }
+
+    protected void runRebindFails(PersistMode persistMode, String dir, String 
errmsg) throws Exception {
+        try {
+            newLauncherDefault(persistMode)
+                    .persistenceDir(dir)
+                    .start();
+        } catch (FatalConfigurationRuntimeException e) {
+            if (!e.toString().contains(errmsg)) {
+                throw e;
+            }
+        }
+    }
+
+    protected void populatePersistenceDir(String dir, EntitySpec<? extends 
StartableApplication> appSpec) throws Exception {
+        BrooklynLauncher launcher = newLauncherDefault(PersistMode.CLEAN)
+                .persistenceDir(dir)
+                .application(appSpec)
+                .start();
+        launcher.terminate();
+        launcher = null;
+        assertMementoContainerNonEmptyForTypeEventually("entities");
+    }
+    
+    protected void assertOnlyApp(ManagementContext managementContext, Class<? 
extends Application> expectedType) {
+        assertEquals(managementContext.getApplications().size(), 1, 
"apps="+managementContext.getApplications());
+        assertNotNull(Iterables.find(managementContext.getApplications(), 
Predicates.instanceOf(TestApplication.class), null), 
"apps="+managementContext.getApplications());
+    }
+    
+    protected void assertMementoContainerNonEmptyForTypeEventually(final 
String type) {
+        Asserts.succeedsEventually(ImmutableMap.of("timeout", 
Duration.TEN_SECONDS), new Runnable() {
+            @Override public void run() {
+                getPersistenceStore(lastMgmt()).listContentsWithSubPath(type);
+            }});
+    }
+
+    static PersistenceObjectStore getPersistenceStore(ManagementContext 
managementContext) {
+        if (managementContext==null) return null;
+        BrooklynMementoPersisterToObjectStore persister = 
(BrooklynMementoPersisterToObjectStore)managementContext.getRebindManager().getPersister();
+        if (persister==null) return null;
+        return persister.getObjectStore();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/32cf5dea/usage/launcher/src/test/java/brooklyn/launcher/BrooklynLauncherRebindTestToFiles.java
----------------------------------------------------------------------
diff --git 
a/usage/launcher/src/test/java/brooklyn/launcher/BrooklynLauncherRebindTestToFiles.java
 
b/usage/launcher/src/test/java/brooklyn/launcher/BrooklynLauncherRebindTestToFiles.java
new file mode 100644
index 0000000..569aa57
--- /dev/null
+++ 
b/usage/launcher/src/test/java/brooklyn/launcher/BrooklynLauncherRebindTestToFiles.java
@@ -0,0 +1,92 @@
+package brooklyn.launcher;
+
+import static org.testng.Assert.assertEquals;
+
+import java.io.File;
+
+import org.testng.annotations.Test;
+
+import brooklyn.config.BrooklynProperties;
+import brooklyn.config.BrooklynServerConfig;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.entity.rebind.persister.BrooklynMementoPersisterToObjectStore;
+import brooklyn.entity.rebind.persister.FileBasedObjectStore;
+import brooklyn.entity.rebind.persister.PersistMode;
+import brooklyn.management.ManagementContext;
+import brooklyn.test.entity.TestApplication;
+import brooklyn.util.javalang.JavaClassNames;
+import brooklyn.util.os.Os;
+import brooklyn.util.text.Identifiers;
+
+import com.google.common.io.Files;
+
+public class BrooklynLauncherRebindTestToFiles extends 
BrooklynLauncherRebindTestFixture {
+
+    protected String newTempPersistenceContainerName() {
+        File persistenceDirF = Files.createTempDir();
+        Os.deleteOnExitRecursively(persistenceDirF);
+        return persistenceDirF.getAbsolutePath();
+    }
+    
+    protected String badContainerName() {
+        return "/path/does/not/exist/"+Identifiers.makeRandomId(4);
+    }
+    
+    protected void checkPersistenceContainerNameIs(String expected) {
+        assertEquals(getPersistenceDir(lastMgmt()).getAbsolutePath(), 
expected);
+    }
+
+    static File getPersistenceDir(ManagementContext managementContext) {
+        BrooklynMementoPersisterToObjectStore persister = 
(BrooklynMementoPersisterToObjectStore)managementContext.getRebindManager().getPersister();
+        FileBasedObjectStore store = 
(FileBasedObjectStore)persister.getObjectStore();
+        return store.getBaseDir();
+    }
+
+    protected void checkPersistenceContainerNameIsDefault() {
+        
checkPersistenceContainerNameIs(BrooklynServerConfig.getPersistenceDir(BrooklynProperties.Factory.newDefault()));
+    }
+
+    @Test
+    public void testPersistenceFailsIfIsFile() throws Exception {
+        File tempF = 
File.createTempFile("test-"+JavaClassNames.niceClassAndMethod(), ".not_dir");
+        tempF.deleteOnExit();
+        String tempFileName = tempF.getAbsolutePath();
+        
+        try {
+            runRebindFails(PersistMode.AUTO, tempFileName, "not a directory");
+            runRebindFails(PersistMode.REBIND, tempFileName, "not a 
directory");
+            runRebindFails(PersistMode.CLEAN, tempFileName, "not a directory");
+        } finally {
+            new File(tempFileName).delete();
+        }
+    }
+    
+    @Test
+    public void testPersistenceFailsIfNotWritable() throws Exception {
+        EntitySpec<TestApplication> appSpec = 
EntitySpec.create(TestApplication.class);
+        populatePersistenceDir(persistenceDir, appSpec);
+        new File(persistenceDir).setWritable(false);
+        try {
+            runRebindFails(PersistMode.AUTO, persistenceDir, "not writable");
+            runRebindFails(PersistMode.REBIND, persistenceDir, "not writable");
+            runRebindFails(PersistMode.CLEAN, persistenceDir, "not writable");
+        } finally {
+            new File(persistenceDir).setWritable(true);
+        }
+    }
+
+    @Test
+    public void testPersistenceFailsIfNotReadable() throws Exception {
+        EntitySpec<TestApplication> appSpec = 
EntitySpec.create(TestApplication.class);
+        populatePersistenceDir(persistenceDir, appSpec);
+        new File(persistenceDir).setReadable(false);
+        try {
+            runRebindFails(PersistMode.AUTO, persistenceDir, "not readable");
+            runRebindFails(PersistMode.REBIND, persistenceDir, "not readable");
+            runRebindFails(PersistMode.CLEAN, persistenceDir, "not readable");
+        } finally {
+            new File(persistenceDir).setReadable(true);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/32cf5dea/usage/launcher/src/test/java/brooklyn/launcher/BrooklynLauncherRebindToCloudObjectStoreTest.java
----------------------------------------------------------------------
diff --git 
a/usage/launcher/src/test/java/brooklyn/launcher/BrooklynLauncherRebindToCloudObjectStoreTest.java
 
b/usage/launcher/src/test/java/brooklyn/launcher/BrooklynLauncherRebindToCloudObjectStoreTest.java
new file mode 100644
index 0000000..15ce172
--- /dev/null
+++ 
b/usage/launcher/src/test/java/brooklyn/launcher/BrooklynLauncherRebindToCloudObjectStoreTest.java
@@ -0,0 +1,58 @@
+package brooklyn.launcher;
+
+import static org.testng.Assert.assertEquals;
+
+import org.testng.annotations.Test;
+
+import brooklyn.config.BrooklynProperties;
+import brooklyn.config.BrooklynServerConfig;
+import brooklyn.entity.rebind.persister.BrooklynMementoPersisterToObjectStore;
+import 
brooklyn.entity.rebind.persister.jclouds.JcloudsBlobStoreBasedObjectStore;
+import brooklyn.management.ManagementContext;
+import brooklyn.test.entity.LocalManagementContextForTests;
+import brooklyn.util.javalang.JavaClassNames;
+import brooklyn.util.text.Identifiers;
+
+@Test(groups="Integration")
+// Jun 2014: Alex has confirmed setting Integration here means that inherited 
methods are NOT run as part of normal build
+public class BrooklynLauncherRebindToCloudObjectStoreTest extends 
BrooklynLauncherRebindTestFixture {
+
+    public static final String LOCATION_SPEC = 
"named:softlayer-objectstore-amsterdam-1";
+    
+    { persistenceLocationSpec = LOCATION_SPEC; }
+    
+    @Override
+    protected BrooklynLauncher newLauncherBase() {
+        return 
super.newLauncherBase().persistenceLocation(persistenceLocationSpec);
+    }
+    
+    protected LocalManagementContextForTests 
newManagementContextForTests(BrooklynProperties props) {
+        BrooklynProperties p2 = BrooklynProperties.Factory.newDefault();
+        if (props!=null) p2.putAll(props);
+        return new LocalManagementContextForTests(p2);
+    }
+
+    @Override
+    protected String newTempPersistenceContainerName() {
+        return 
"test-"+JavaClassNames.callerStackElement(0).getClassName()+"-"+Identifiers.makeRandomId(4);
+    }
+    
+    protected String badContainerName() {
+        return "container-does-not-exist-"+Identifiers.makeRandomId(4);
+    }
+    
+    protected void checkPersistenceContainerNameIs(String expected) {
+        assertEquals(getPersistenceContainerName(lastMgmt()), expected);
+    }
+
+    static String getPersistenceContainerName(ManagementContext 
managementContext) {
+        BrooklynMementoPersisterToObjectStore persister = 
(BrooklynMementoPersisterToObjectStore)managementContext.getRebindManager().getPersister();
+        JcloudsBlobStoreBasedObjectStore store = 
(JcloudsBlobStoreBasedObjectStore)persister.getObjectStore();
+        return store.getContainerName();
+    }
+
+    protected void checkPersistenceContainerNameIsDefault() {
+        
checkPersistenceContainerNameIs(BrooklynServerConfig.PERSISTENCE_PATH_SEGMENT);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/32cf5dea/utils/common/src/main/java/brooklyn/util/exceptions/FatalConfigurationRuntimeException.java
----------------------------------------------------------------------
diff --git 
a/utils/common/src/main/java/brooklyn/util/exceptions/FatalConfigurationRuntimeException.java
 
b/utils/common/src/main/java/brooklyn/util/exceptions/FatalConfigurationRuntimeException.java
new file mode 100644
index 0000000..4a57a3e
--- /dev/null
+++ 
b/utils/common/src/main/java/brooklyn/util/exceptions/FatalConfigurationRuntimeException.java
@@ -0,0 +1,15 @@
+package brooklyn.util.exceptions;
+
+/** Exception indicating a fatal config error, typically used in CLI routines. 
*/
+public class FatalConfigurationRuntimeException extends RuntimeException {
+
+    private static final long serialVersionUID = -5361951925760434821L;
+
+    public FatalConfigurationRuntimeException(String message) {
+        super(message);
+    }
+    
+    public FatalConfigurationRuntimeException(String message, Throwable cause) 
{
+        super(message, cause);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/32cf5dea/utils/common/src/main/java/brooklyn/util/os/Os.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/os/Os.java 
b/utils/common/src/main/java/brooklyn/util/os/Os.java
index 0123a7b..9257452 100644
--- a/utils/common/src/main/java/brooklyn/util/os/Os.java
+++ b/utils/common/src/main/java/brooklyn/util/os/Os.java
@@ -177,7 +177,7 @@ public class Os {
         char separatorChar = File.separatorChar;
         StringBuilder result = new StringBuilder();
         for (String item: items) {
-            if (item.isEmpty()) continue;
+            if (Strings.isEmpty(item)) continue;
             if (result.length() > 0 && result.charAt(result.length()-1) != 
separatorChar) result.append(separatorChar);
             result.append(item);
         }

Reply via email to