You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by ri...@apache.org on 2014/07/08 19:00:37 UTC

[1/5] git commit: Logging in BrooklynFeatureEnablement.setDefault

Repository: incubator-brooklyn
Updated Branches:
  refs/heads/master 73dcb1d8d -> 35dce9b92


Logging in BrooklynFeatureEnablement.setDefault


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

Branch: refs/heads/master
Commit: 09ade725201712836b343b2fbf82f5edfb04f028
Parents: 45a3b5f
Author: Aled Sage <al...@gmail.com>
Authored: Fri Jul 4 12:56:49 2014 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Jul 8 15:00:29 2014 +0100

----------------------------------------------------------------------
 .../java/brooklyn/internal/BrooklynFeatureEnablement.java    | 8 ++++++++
 1 file changed, 8 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09ade725/core/src/main/java/brooklyn/internal/BrooklynFeatureEnablement.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/internal/BrooklynFeatureEnablement.java b/core/src/main/java/brooklyn/internal/BrooklynFeatureEnablement.java
index 9bfc188..d5fe674 100644
--- a/core/src/main/java/brooklyn/internal/BrooklynFeatureEnablement.java
+++ b/core/src/main/java/brooklyn/internal/BrooklynFeatureEnablement.java
@@ -2,6 +2,9 @@ package brooklyn.internal;
 
 import java.util.Map;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import com.google.common.collect.Maps;
 
 /**
@@ -14,6 +17,8 @@ import com.google.common.collect.Maps;
  */
 public class BrooklynFeatureEnablement {
 
+    private static final Logger LOG = LoggerFactory.getLogger(BrooklynFeatureEnablement.class);
+
     public static final String FEATURE_POLICY_PERSISTENCE_PROPERTY = "brooklyn.experimental.feature.policyPersistence";
     
     public static final String FEATURE_ENRICHER_PERSISTENCE_PROPERTY = "brooklyn.experimental.feature.enricherPersistence";
@@ -68,6 +73,9 @@ public class BrooklynFeatureEnablement {
                 String rawVal = System.getProperty(property);
                 if (rawVal == null) {
                     FEATURE_ENABLEMENTS.put(property, val);
+                    LOG.debug("Default enablement of "+property+" set to "+val);
+                } else {
+                    LOG.debug("Not setting default enablement of "+property+" to "+val+", because system property is "+rawVal);
                 }
             }
         }


[4/5] git commit: JcloudsLocation: log port when waiting to ssh

Posted by ri...@apache.org.
JcloudsLocation: log port when waiting to ssh


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

Branch: refs/heads/master
Commit: 0cff1f2b20bf4ed60b23daa83b583720fcbc7d3c
Parents: 09ade72
Author: Aled Sage <al...@gmail.com>
Authored: Tue Jul 8 15:00:10 2014 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Jul 8 15:00:30 2014 +0100

----------------------------------------------------------------------
 .../main/java/brooklyn/location/jclouds/JcloudsLocation.java  | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0cff1f2b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
index e4fde3e..06d5759 100644
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
+++ b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
@@ -1678,6 +1678,8 @@ public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation im
         String vmIp = hostAndPortOverride.isPresent() ? hostAndPortOverride.get().getHostText() : JcloudsUtil.getFirstReachableAddress(computeService.getContext(), node);
         if (vmIp==null) LOG.warn("Unable to extract IP for "+node+" ("+setup.getDescription()+"): subsequent connection attempt will likely fail");
         
+        int vmPort = hostAndPortOverride.isPresent() ? hostAndPortOverride.get().getPortOrDefault(22) : 22;
+        
         long delayMs = -1;
         try {
             delayMs = Time.parseTimeString(""+waitForSshable);
@@ -1688,9 +1690,10 @@ public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation im
             delayMs = Time.parseTimeString(WAIT_FOR_SSHABLE.getDefaultValue());
         
         String user = expectedCredentials.getUser();
-        LOG.debug("VM {}: reported online, now waiting {} for it to be sshable on {}@{}{}", new Object[] {
+        LOG.debug("VM {}: reported online, now waiting {} for it to be sshable on {}@{}:{}{}", new Object[] {
                 setup.getDescription(), Time.makeTimeStringRounded(delayMs),
-                user, vmIp, Objects.equal(user, getUser(setup)) ? "" : " (setup user is different: "+getUser(setup)+")"});
+                user, vmIp, vmPort,
+                Objects.equal(user, getUser(setup)) ? "" : " (setup user is different: "+getUser(setup)+")"});
         
         Callable<Boolean> checker;
         if (hostAndPortOverride.isPresent()) {


[2/5] git commit: Mark getting machine details as “inessential”

Posted by ri...@apache.org.
Mark getting machine details as “inessential”


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

Branch: refs/heads/master
Commit: 45a3b5f1276fc62ee0d2381358a60ec3177c0d94
Parents: d591c81
Author: Aled Sage <al...@gmail.com>
Authored: Thu Jul 3 19:53:14 2014 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Jul 8 15:00:29 2014 +0100

----------------------------------------------------------------------
 .../location/basic/BasicMachineDetails.java     |  10 +-
 .../location/basic/SshMachineLocationTest.java  | 109 ++++++++++++++++++-
 .../jclouds/JcloudsSshMachineLocation.java      |  14 ++-
 .../src/main/java/brooklyn/test/Asserts.java    |  45 ++++++++
 .../test/java/brooklyn/test/AssertsTest.java    |  58 ++++++++++
 5 files changed, 222 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/45a3b5f1/core/src/main/java/brooklyn/location/basic/BasicMachineDetails.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/BasicMachineDetails.java b/core/src/main/java/brooklyn/location/basic/BasicMachineDetails.java
index d1361fa..a680d6d 100644
--- a/core/src/main/java/brooklyn/location/basic/BasicMachineDetails.java
+++ b/core/src/main/java/brooklyn/location/basic/BasicMachineDetails.java
@@ -4,7 +4,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.io.BufferedReader;
 import java.io.IOException;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
@@ -21,19 +20,16 @@ import brooklyn.management.Task;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.stream.Streams;
 import brooklyn.util.task.DynamicTasks;
+import brooklyn.util.task.TaskTags;
 import brooklyn.util.task.ssh.internal.PlainSshExecTaskFactory;
 import brooklyn.util.task.system.ProcessTaskWrapper;
-import brooklyn.util.text.Strings;
 
 import com.google.common.base.CharMatcher;
 import com.google.common.base.Function;
 import com.google.common.base.Joiner;
 import com.google.common.base.Objects;
-import com.google.common.base.Optional;
 import com.google.common.base.Splitter;
 import com.google.common.base.Throwables;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.io.CharStreams;
 
@@ -77,9 +73,9 @@ public class BasicMachineDetails implements MachineDetails {
      * #taskForSshMachineLocation(SshMachineLocation)} instead.
      */
     static BasicMachineDetails forSshMachineLocation(SshMachineLocation location) {
-        return DynamicTasks.queueIfPossible(taskForSshMachineLocation(location))
+        return TaskTags.markInessential(DynamicTasks.queueIfPossible(taskForSshMachineLocation(location))
                 .orSubmitAsync()
-                .asTask()
+                .asTask())
                 .getUnchecked();
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/45a3b5f1/core/src/test/java/brooklyn/location/basic/SshMachineLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/SshMachineLocationTest.java b/core/src/test/java/brooklyn/location/basic/SshMachineLocationTest.java
index f4fa966..9dd08ed 100644
--- a/core/src/test/java/brooklyn/location/basic/SshMachineLocationTest.java
+++ b/core/src/test/java/brooklyn/location/basic/SshMachineLocationTest.java
@@ -2,29 +2,60 @@ package brooklyn.location.basic;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
 import static org.testng.Assert.assertTrue;
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.OutputStream;
 import java.net.InetAddress;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
 
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+import brooklyn.entity.Effector;
+import brooklyn.entity.basic.ApplicationBuilder;
+import brooklyn.entity.basic.BrooklynConfigKeys;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.EntityInternal;
+import brooklyn.entity.basic.EntityLocal;
+import brooklyn.entity.effector.EffectorBody;
+import brooklyn.entity.effector.EffectorTaskTest;
+import brooklyn.entity.effector.Effectors;
+import brooklyn.entity.proxying.EntityInitializer;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.location.LocationSpec;
+import brooklyn.location.MachineDetails;
+import brooklyn.location.MachineLocation;
 import brooklyn.location.PortRange;
 import brooklyn.location.basic.PortRanges.LinearPortRange;
+import brooklyn.management.ManagementContext;
+import brooklyn.test.Asserts;
+import brooklyn.test.entity.LocalManagementContextForTests;
+import brooklyn.test.entity.TestApplication;
 import brooklyn.util.collections.MutableMap;
+import brooklyn.util.config.ConfigBag;
 import brooklyn.util.file.ArchiveUtils;
+import brooklyn.util.guava.Maybe;
+import brooklyn.util.internal.ssh.RecordingSshTool;
 import brooklyn.util.internal.ssh.SshException;
+import brooklyn.util.internal.ssh.SshTool;
 import brooklyn.util.net.Networking;
 import brooklyn.util.net.Urls;
 import brooklyn.util.os.Os;
 import brooklyn.util.stream.Streams;
+import brooklyn.util.task.BasicExecutionContext;
+import brooklyn.util.task.BasicExecutionManager;
+import brooklyn.util.time.Duration;
 
 import com.google.common.base.Charsets;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.io.Files;
 
@@ -34,6 +65,7 @@ import com.google.common.io.Files;
 public class SshMachineLocationTest {
 
     private SshMachineLocation host;
+    private ManagementContext mgmt;
     
     @BeforeMethod(alwaysRun=true)
     public void setUp() throws Exception {
@@ -43,6 +75,72 @@ public class SshMachineLocationTest {
     @AfterMethod(alwaysRun=true)
     public void tearDown() throws Exception {
         if (host != null) Streams.closeQuietly(host);
+        if (mgmt != null) Entities.destroyAll(mgmt);
+    }
+    
+    @Test(groups = "Integration")
+    public void testGetMachineDetails() throws Exception {
+        BasicExecutionManager execManager = new BasicExecutionManager("mycontextid");
+        BasicExecutionContext execContext = new BasicExecutionContext(execManager);
+        try {
+            MachineDetails details = execContext.submit(new Callable<MachineDetails>() {
+                public MachineDetails call() {
+                    return host.getMachineDetails();
+                }}).get();
+            assertNotNull(details);
+        } finally {
+            execManager.shutdownNow();
+        }
+    }
+    
+    // Wow, this is hard to test (until I accepted creating the entity + effector)! Code smell?
+    // Need to call getMachineDetails in a DynamicSequentialTask so that the "innessential" takes effect,
+    // to not fail its caller. But to get one of those outside of an effector is non-obvious.
+    @Test(groups = "Integration")
+    public void testGetMachineIsInessentialOnFailure() throws Exception {
+        ManagementContext mgmt = new LocalManagementContextForTests();
+        
+        SshMachineLocation host2 = mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
+                .configure("address", Networking.getLocalHost())
+                .configure(SshTool.PROP_TOOL_CLASS, FailingSshTool.class.getName()));
+
+        final Effector<MachineDetails> GET_MACHINE_DETAILS = Effectors.effector(MachineDetails.class, "getMachineDetails")
+                .impl(new EffectorBody<MachineDetails>() {
+                    public MachineDetails call(ConfigBag parameters) {
+                        Maybe<MachineLocation> machine = Machines.findUniqueMachineLocation(entity().getLocations());
+                        try {
+                            machine.get().getMachineDetails();
+                            throw new IllegalStateException("Expected failure in ssh");
+                        } catch (RuntimeException e) {
+                            return null;
+                        }
+                    }})
+                .build();
+
+        EntitySpec<TestApplication> appSpec = EntitySpec.create(TestApplication.class)
+                .configure(BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, true)
+                .addInitializer(new EntityInitializer() {
+                        public void apply(EntityLocal entity) {
+                            ((EntityInternal)entity).getMutableEntityType().addEffector(EffectorTaskTest.DOUBLE_1);
+                        }});
+
+        TestApplication app = ApplicationBuilder.newManagedApp(appSpec, mgmt);
+
+        app.start(ImmutableList.of(host2));
+        
+        MachineDetails details = app.invoke(GET_MACHINE_DETAILS, ImmutableMap.<String, Object>of()).get();
+        assertNull(details);
+    }
+    public static class FailingSshTool extends RecordingSshTool {
+        public FailingSshTool(Map<?, ?> props) {
+            super(props);
+        }
+        @Override public int execScript(Map<String, ?> props, List<String> commands, Map<String, ?> env) {
+            throw new RuntimeException("Simulating failure of ssh: cmds="+commands);
+        }
+        @Override public int execCommands(Map<String, ?> props, List<String> commands, Map<String, ?> env) {
+            throw new RuntimeException("Simulating failure of ssh: cmds="+commands);
+        }
     }
     
     // Note: requires `ssh localhost` to be setup such that no password is required    
@@ -148,12 +246,17 @@ public class SshMachineLocationTest {
         assertTrue(host.isSshable());
     }
     
-    // Note: requires `ssh localhost` to be setup such that no password is required    
+    // Note: on some (home/airport) networks, `ssh 123.123.123.123` hangs seemingly forever.
+    // Make sure we fail, waiting for longer than the 70 second TCP timeout.
     @Test(groups = "Integration")
     public void testIsSshableWhenFalse() throws Exception {
         byte[] unreachableIp = new byte[] {123,123,123,123};
-        SshMachineLocation unreachableHost = new SshMachineLocation(MutableMap.of("address", InetAddress.getByAddress("unreachablename", unreachableIp)));
-        assertFalse(unreachableHost.isSshable());
+        final SshMachineLocation unreachableHost = new SshMachineLocation(MutableMap.of("address", InetAddress.getByAddress("unreachablename", unreachableIp)));
+        Asserts.assertReturnsEventually(new Runnable() {
+            public void run() {
+                assertFalse(unreachableHost.isSshable());
+            }},
+            Duration.TWO_MINUTES);
     }
     
     @Test

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/45a3b5f1/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsSshMachineLocation.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsSshMachineLocation.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsSshMachineLocation.java
index ad05973..1fd8e89 100644
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsSshMachineLocation.java
+++ b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsSshMachineLocation.java
@@ -37,6 +37,7 @@ import brooklyn.location.basic.BasicMachineDetails;
 import brooklyn.location.basic.BasicOsDetails;
 import brooklyn.location.basic.HasSubnetHostname;
 import brooklyn.location.basic.SshMachineLocation;
+import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.flags.SetFromFlag;
 import brooklyn.util.net.Networking;
 import brooklyn.util.text.Strings;
@@ -288,10 +289,15 @@ public class JcloudsSshMachineLocation extends SshMachineLocation implements Has
         putIfNotNull(builder, "ram", "" + (hardware != null ? hardware.getRam() : null));
         putIfNotNull(builder, "cpus", "" + (processors != null ? processors.size() : null));
         
-        OsDetails osDetails = getOsDetails();
-        putIfNotNull(builder, "osName", osDetails.getName());
-        putIfNotNull(builder, "osArch", osDetails.getArch());
-        putIfNotNull(builder, "64bit", osDetails.is64bit() ? "true" : "false");
+        try {
+            OsDetails osDetails = getOsDetails();
+            putIfNotNull(builder, "osName", osDetails.getName());
+            putIfNotNull(builder, "osArch", osDetails.getArch());
+            putIfNotNull(builder, "64bit", osDetails.is64bit() ? "true" : "false");
+        } catch (Exception e) {
+            Exceptions.propagateIfFatal(e);
+            LOG.warn("Unable to get OS Details for "+node+"; continuing", e);
+        }
         
         return builder.build();
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/45a3b5f1/utils/common/src/main/java/brooklyn/test/Asserts.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/test/Asserts.java b/utils/common/src/main/java/brooklyn/test/Asserts.java
index be98183..30bbe06 100644
--- a/utils/common/src/main/java/brooklyn/test/Asserts.java
+++ b/utils/common/src/main/java/brooklyn/test/Asserts.java
@@ -2,6 +2,7 @@ package brooklyn.test;
 
 import groovy.lang.Closure;
 
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Enumeration;
 import java.util.Iterator;
@@ -9,12 +10,16 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executors;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicReference;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.util.collections.MutableSet;
+import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.time.Duration;
 
 import com.google.common.annotations.Beta;
@@ -60,6 +65,16 @@ public class Asserts {
     }
 
     /**
+     * Asserts that a condition is false. If it isn't,
+     * an AssertionError, with the given message, is thrown.
+     * @param condition the condition to evaluate
+     * @param message the assertion error message
+     */
+    public static void assertFalse(boolean condition, String message) {
+        if (condition) fail(message);
+    }
+
+    /**
      * Fails a test with the given message.
      * @param message the assertion error message
      */
@@ -358,6 +373,36 @@ public class Asserts {
         if (!failed) fail("Test code should have thrown exception but did not");
     }
 
+    public static void assertReturnsEventually(final Runnable r, Duration timeout) throws InterruptedException, ExecutionException, TimeoutException {
+        final AtomicReference<Throwable> throwable = new AtomicReference<Throwable>();
+        Runnable wrappedR = new Runnable() {
+            @Override public void run() {
+                try {
+                    r.run();
+                } catch (Throwable t) {
+                    throwable.set(t);
+                    throw Exceptions.propagate(t);
+                }
+            }
+        };
+        Thread thread = new Thread(wrappedR, "assertReturnsEventually("+r+")");
+        try {
+            thread.start();
+            thread.join(timeout.toMilliseconds());
+            if (thread.isAlive()) {
+                throw new TimeoutException("Still running: r="+r+"; thread="+Arrays.toString(thread.getStackTrace()));
+            }
+        } catch (InterruptedException e) {
+            throw Exceptions.propagate(e);
+        } finally {
+            thread.interrupt();
+        }
+        
+        if (throwable.get() !=  null) {
+            throw new ExecutionException(throwable.get());
+        }
+    }
+    
     @SuppressWarnings("rawtypes")
     private static boolean groovyTruth(Object o) {
         // TODO Doesn't handle matchers (see http://docs.codehaus.org/display/GROOVY/Groovy+Truth)

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/45a3b5f1/utils/common/src/test/java/brooklyn/test/AssertsTest.java
----------------------------------------------------------------------
diff --git a/utils/common/src/test/java/brooklyn/test/AssertsTest.java b/utils/common/src/test/java/brooklyn/test/AssertsTest.java
index 38bf2ba..b43d1b7 100644
--- a/utils/common/src/test/java/brooklyn/test/AssertsTest.java
+++ b/utils/common/src/test/java/brooklyn/test/AssertsTest.java
@@ -1,14 +1,26 @@
 package brooklyn.test;
 
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import brooklyn.util.collections.MutableMap;
+import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.time.Duration;
 
 import com.google.common.util.concurrent.Callables;
 
 public class AssertsTest {
 
+    private static final Runnable NOOP_RUNNABLE = new Runnable() {
+        @Override public void run() {
+        }
+    };
+    
     // TODO this is confusing -- i'd expect it to fail since it always returns false;
     // see notes at start of Asserts and in succeedsEventually method
     @Test
@@ -16,4 +28,50 @@ public class AssertsTest {
         Asserts.succeedsEventually(MutableMap.of("timeout", Duration.millis(50)), Callables.returning(false));
     }
     
+    @Test
+    public void testAssertReturnsEventually() throws Exception {
+        Asserts.assertReturnsEventually(NOOP_RUNNABLE, Duration.THIRTY_SECONDS);
+    }
+    
+    @Test
+    public void testAssertReturnsEventuallyTimesOut() throws Exception {
+        final AtomicBoolean interrupted = new AtomicBoolean();
+        
+        try {
+            Asserts.assertReturnsEventually(new Runnable() {
+                public void run() {
+                    try {
+                        Thread.sleep(60*1000);
+                    } catch (InterruptedException e) {
+                        interrupted.set(true);
+                        Thread.currentThread().interrupt();
+                        return;
+                    }
+                }},
+                Duration.of(10, TimeUnit.MILLISECONDS));
+            Assert.fail("Should have thrown AssertionError on timeout");
+        } catch (TimeoutException e) {
+            // success
+        }
+        
+        Asserts.succeedsEventually(new Runnable() {
+            @Override public void run() {
+                Assert.assertTrue(interrupted.get());
+            }});
+    }
+    
+    @Test
+    public void testAssertReturnsEventuallyPropagatesException() throws Exception {
+        try {
+            Asserts.assertReturnsEventually(new Runnable() {
+                public void run() {
+                    throw new IllegalStateException("Simulating failure");
+                }},
+                Duration.THIRTY_SECONDS);
+            Assert.fail("Should have thrown AssertionError on timeout");
+        } catch (ExecutionException e) {
+            IllegalStateException ise = Exceptions.getFirstThrowableOfType(e, IllegalStateException.class);
+            if (ise == null || !ise.toString().contains("Simulating failure")) throw e;
+        }
+    }
 }


[3/5] git commit: Moves RecordingSshTool to core

Posted by ri...@apache.org.
Moves RecordingSshTool to core


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

Branch: refs/heads/master
Commit: d591c813f4139e8bd99bb6da9c12744dfa48019a
Parents: 73dcb1d
Author: Aled Sage <al...@gmail.com>
Authored: Fri Jul 4 21:17:13 2014 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Jul 8 15:00:29 2014 +0100

----------------------------------------------------------------------
 .../util/internal/ssh/RecordingSshTool.java     | 76 ++++++++++++++++++++
 .../java/brooklyn/entity/java/JavaOptsTest.java | 71 +-----------------
 2 files changed, 78 insertions(+), 69 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d591c813/core/src/test/java/brooklyn/util/internal/ssh/RecordingSshTool.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/util/internal/ssh/RecordingSshTool.java b/core/src/test/java/brooklyn/util/internal/ssh/RecordingSshTool.java
new file mode 100644
index 0000000..0aa2644
--- /dev/null
+++ b/core/src/test/java/brooklyn/util/internal/ssh/RecordingSshTool.java
@@ -0,0 +1,76 @@
+package brooklyn.util.internal.ssh;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+
+public class RecordingSshTool implements SshTool {
+    
+    public static class ExecCmd {
+        public final Map<String,?> props;
+        public final String summaryForLogging;
+        public final List<String> commands;
+        public final Map<?,?> env;
+        
+        ExecCmd(Map<String,?> props, String summaryForLogging, List<String> commands, Map env) {
+            this.props = props;
+            this.summaryForLogging = summaryForLogging;
+            this.commands = commands;
+            this.env = env;
+        }
+        
+        @Override
+        public String toString() {
+            return "ExecCmd["+summaryForLogging+": "+commands+"; "+props+"; "+env+"]";
+        }
+    }
+    
+    public static List<ExecCmd> execScriptCmds = Lists.newCopyOnWriteArrayList();
+    
+    private boolean connected;
+    
+    public RecordingSshTool(Map<?,?> props) {
+    }
+    @Override public void connect() {
+        connected = true;
+    }
+    @Override public void connect(int maxAttempts) {
+        connected = true;
+    }
+    @Override public void disconnect() {
+        connected = false;
+    }
+    @Override public boolean isConnected() {
+        return connected;
+    }
+    @Override public int execScript(Map<String, ?> props, List<String> commands, Map<String, ?> env) {
+        execScriptCmds.add(new ExecCmd(props, "", commands, env));
+        return 0;
+    }
+    @Override public int execScript(Map<String, ?> props, List<String> commands) {
+        return execScript(props, commands, ImmutableMap.<String,Object>of());
+    }
+    @Override public int execCommands(Map<String, ?> props, List<String> commands, Map<String, ?> env) {
+        execScriptCmds.add(new ExecCmd(props, "", commands, env));
+        return 0;
+    }
+    @Override public int execCommands(Map<String, ?> props, List<String> commands) {
+        return execCommands(props, commands, ImmutableMap.<String,Object>of());
+    }
+    @Override public int copyToServer(Map<String, ?> props, File localFile, String pathAndFileOnRemoteServer) {
+        return 0;
+    }
+    @Override public int copyToServer(Map<String, ?> props, InputStream contents, String pathAndFileOnRemoteServer) {
+        return 0;
+    }
+    @Override public int copyToServer(Map<String, ?> props, byte[] contents, String pathAndFileOnRemoteServer) {
+        return 0;
+    }
+    @Override public int copyFromServer(Map<String, ?> props, String pathAndFileOnRemoteServer, File local) {
+        return 0;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d591c813/software/base/src/test/java/brooklyn/entity/java/JavaOptsTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/java/JavaOptsTest.java b/software/base/src/test/java/brooklyn/entity/java/JavaOptsTest.java
index 62623fc..788b0dc 100644
--- a/software/base/src/test/java/brooklyn/entity/java/JavaOptsTest.java
+++ b/software/base/src/test/java/brooklyn/entity/java/JavaOptsTest.java
@@ -2,8 +2,6 @@ package brooklyn.entity.java;
 
 import static org.testng.Assert.fail;
 
-import java.io.File;
-import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Iterator;
@@ -26,13 +24,14 @@ import brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;
+import brooklyn.util.internal.ssh.RecordingSshTool;
+import brooklyn.util.internal.ssh.RecordingSshTool.ExecCmd;
 import brooklyn.util.internal.ssh.SshTool;
 import brooklyn.util.jmx.jmxmp.JmxmpAgent;
 import brooklyn.util.text.Strings;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
 import com.google.common.collect.MapDifference.ValueDifference;
 import com.google.common.collect.Maps;
 
@@ -44,72 +43,6 @@ public class JavaOptsTest extends BrooklynAppUnitTestSupport {
     
     private static final Logger log = LoggerFactory.getLogger(JavaOptsTest.class);
     
-    private static class ExecCmd {
-        Map<String,?> props;
-        String summaryForLogging;
-        List<String> commands;
-        Map<?,?> env;
-        
-        ExecCmd(Map<String,?> props, String summaryForLogging, List<String> commands, Map env) {
-            this.props = props;
-            this.summaryForLogging = summaryForLogging;
-            this.commands = commands;
-            this.env = env;
-        }
-        
-        @Override
-        public String toString() {
-            return "ExecCmd["+summaryForLogging+": "+commands+"; "+props+"; "+env+"]";
-        }
-    }
-    
-    public static class RecordingSshTool implements SshTool {
-        static List<ExecCmd> execScriptCmds = Lists.newCopyOnWriteArrayList();
-        
-        private boolean connected;
-        
-        public RecordingSshTool(Map<?,?> props) {
-        }
-        @Override public void connect() {
-            connected = true;
-        }
-        @Override public void connect(int maxAttempts) {
-            connected = true;
-        }
-        @Override public void disconnect() {
-            connected = false;
-        }
-        @Override public boolean isConnected() {
-            return connected;
-        }
-        @Override public int execScript(Map<String, ?> props, List<String> commands, Map<String, ?> env) {
-            execScriptCmds.add(new ExecCmd(props, "", commands, env));
-            return 0;
-        }
-        @Override public int execScript(Map<String, ?> props, List<String> commands) {
-            return execScript(props, commands, ImmutableMap.<String,Object>of());
-        }
-        @Override public int execCommands(Map<String, ?> props, List<String> commands, Map<String, ?> env) {
-            execScriptCmds.add(new ExecCmd(props, "", commands, env));
-            return 0;
-        }
-        @Override public int execCommands(Map<String, ?> props, List<String> commands) {
-            return execCommands(props, commands, ImmutableMap.<String,Object>of());
-        }
-        @Override public int copyToServer(Map<String, ?> props, File localFile, String pathAndFileOnRemoteServer) {
-            return 0;
-        }
-        @Override public int copyToServer(Map<String, ?> props, InputStream contents, String pathAndFileOnRemoteServer) {
-            return 0;
-        }
-        @Override public int copyToServer(Map<String, ?> props, byte[] contents, String pathAndFileOnRemoteServer) {
-            return 0;
-        }
-        @Override public int copyFromServer(Map<String, ?> props, String pathAndFileOnRemoteServer, File local) {
-            return 0;
-        }
-    }
-
     private SshMachineLocation loc;
     
     @BeforeMethod(alwaysRun=true)


[5/5] git commit: Merge and close PR #52

Posted by ri...@apache.org.
Merge and close PR #52


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

Branch: refs/heads/master
Commit: 35dce9b92bc92d3221c2142f73b6ab8d04132e5e
Parents: 73dcb1d 0cff1f2
Author: Richard Downer <ri...@apache.org>
Authored: Tue Jul 8 18:00:13 2014 +0100
Committer: Richard Downer <ri...@apache.org>
Committed: Tue Jul 8 18:00:13 2014 +0100

----------------------------------------------------------------------
 .../internal/BrooklynFeatureEnablement.java     |   8 ++
 .../location/basic/BasicMachineDetails.java     |  10 +-
 .../location/basic/SshMachineLocationTest.java  | 109 ++++++++++++++++++-
 .../util/internal/ssh/RecordingSshTool.java     |  76 +++++++++++++
 .../location/jclouds/JcloudsLocation.java       |   7 +-
 .../jclouds/JcloudsSshMachineLocation.java      |  14 ++-
 .../java/brooklyn/entity/java/JavaOptsTest.java |  71 +-----------
 .../src/main/java/brooklyn/test/Asserts.java    |  45 ++++++++
 .../test/java/brooklyn/test/AssertsTest.java    |  58 ++++++++++
 9 files changed, 313 insertions(+), 85 deletions(-)
----------------------------------------------------------------------