You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by gr...@apache.org on 2016/12/01 16:03:24 UTC

[1/4] brooklyn-server git commit: SshMachineLocationTest: make non-integration

Repository: brooklyn-server
Updated Branches:
  refs/heads/master 50826cbc2 -> 615c63574


SshMachineLocationTest: make non-integration

* Uses RecordingSshTool
* Moves integration tests into SshMachineLocationIntegrationTest
* Changes SshMachineLocationIntegrationTest to extends 
  SshMachineLocationTest.

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

Branch: refs/heads/master
Commit: e5b40cc1866854d8966099c26ea44a62cd9c3196
Parents: b11c87d
Author: Aled Sage <al...@gmail.com>
Authored: Thu Dec 1 08:26:56 2016 +0000
Committer: Aled Sage <al...@gmail.com>
Committed: Thu Dec 1 08:26:56 2016 +0000

----------------------------------------------------------------------
 .../ssh/SshMachineLocationIntegrationTest.java  | 184 +++++++++++++++++--
 .../location/ssh/SshMachineLocationTest.java    | 160 +++++-----------
 2 files changed, 210 insertions(+), 134 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/e5b40cc1/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationIntegrationTest.java
index 605d9c0..1def66f 100644
--- a/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationIntegrationTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationIntegrationTest.java
@@ -19,53 +19,199 @@
 package org.apache.brooklyn.location.ssh;
 
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
 
 import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.OutputStream;
+import java.net.InetAddress;
 import java.security.KeyPair;
 import java.util.Arrays;
 import java.util.Map;
+import java.util.concurrent.Callable;
 
 import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.location.LocationSpec;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
-import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.api.location.MachineDetails;
+import org.apache.brooklyn.core.entity.AbstractEntity;
+import org.apache.brooklyn.core.internal.BrooklynProperties;
 import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.test.Asserts;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.crypto.SecureKeys;
+import org.apache.brooklyn.util.core.file.ArchiveUtils;
+import org.apache.brooklyn.util.core.internal.ssh.SshException;
 import org.apache.brooklyn.util.core.internal.ssh.SshTool;
 import org.apache.brooklyn.util.core.internal.ssh.sshj.SshjTool;
 import org.apache.brooklyn.util.core.internal.ssh.sshj.SshjTool.SshjToolBuilder;
+import org.apache.brooklyn.util.core.task.BasicExecutionContext;
+import org.apache.brooklyn.util.core.task.BasicExecutionManager;
 import org.apache.brooklyn.util.guava.Maybe;
+import org.apache.brooklyn.util.net.Networking;
+import org.apache.brooklyn.util.net.Urls;
+import org.apache.brooklyn.util.os.Os;
+import org.apache.brooklyn.util.stream.Streams;
+import org.apache.brooklyn.util.time.Duration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+import com.google.common.base.Charsets;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
+import com.google.common.io.Files;
 
-public class SshMachineLocationIntegrationTest {
+public class SshMachineLocationIntegrationTest extends SshMachineLocationTest {
 
-    protected TestApplication app;
-    protected ManagementContext mgmt;
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractEntity.class);
 
-    @BeforeMethod(alwaysRun=true)
-    public void setup() throws Exception {
-        mgmt = LocalManagementContextForTests.builder(true)
-            .useDefaultProperties()
-            .build();
-        app = TestApplication.Factory.newManagedInstanceForTests(mgmt);
+    @Override
+    protected BrooklynProperties getBrooklynProperties() {
+        // Requires location named "localhost-passphrase", which it expects to find in local 
+        // brooklyn.properties (or brooklyn.cfg in karaf).
+        return BrooklynProperties.Factory.newDefault();
+    }
+    
+    @Override
+    protected SshMachineLocation newHost() {
+        return mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
+                .configure("address", Networking.getLocalHost()));
+    }
+
+    // Overridden just to make it integration (because `newHost()` returns a real ssh'ing host)
+    @Test(groups="Integration")
+    @Override
+    public void testSshExecScript() throws Exception {
+        super.testSshExecScript();
+    }
+    
+    // Overridden just to make it integration (because `newHost()` returns a real ssh'ing host)
+    @Test(groups="Integration")
+    @Override
+    public void testSshExecCommands() throws Exception {
+        super.testSshExecCommands();
+    }
+    
+    // Overridden just to make it integration (because `newHost()` returns a real ssh'ing host)
+    @Test(groups="Integration")
+    @Override
+    public void testIsSshableWhenTrue() throws Exception {
+        super.testIsSshableWhenTrue();
     }
 
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (mgmt != null) Entities.destroyAll(mgmt);
-        mgmt = null;
+    // Overrides super, because expect real machine details (rather than asserting our stub data)
+    @Test(groups = "Integration")
+    @Override
+    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();
+            LOG.info("machineDetails="+details);
+            assertNotNull(details);
+        } finally {
+            execManager.shutdownNow();
+        }
+    }
+
+    @Test(groups = "Integration")
+    public void testCopyFileTo() throws Exception {
+        File dest = Os.newTempFile(getClass(), ".dest.tmp");
+        File src = Os.newTempFile(getClass(), ".src.tmp");
+        try {
+            Files.write("abc", src, Charsets.UTF_8);
+            host.copyTo(src, dest);
+            assertEquals("abc", Files.readFirstLine(dest, Charsets.UTF_8));
+        } finally {
+            src.delete();
+            dest.delete();
+        }
     }
 
+    // Note: requires `ssh localhost` to be setup such that no password is required    
+    @Test(groups = "Integration")
+    public void testCopyStreamTo() throws Exception {
+        String contents = "abc";
+        File dest = new File(Os.tmp(), "sshMachineLocationTest_dest.tmp");
+        try {
+            host.copyTo(Streams.newInputStreamWithContents(contents), dest.getAbsolutePath());
+            assertEquals("abc", Files.readFirstLine(dest, Charsets.UTF_8));
+        } finally {
+            dest.delete();
+        }
+    }
+
+    // Requires internet connectivity; on guest wifi etc can fail with things like
+    // "Welcome to Virgin Trains" etc.
+    @Test(groups = "Integration")
+    public void testInstallUrlTo() throws Exception {
+        File dest = new File(Os.tmp(), "sshMachineLocationTest_dir/");
+        dest.mkdir();
+        try {
+            int result = host.installTo("https://raw.github.com/brooklyncentral/brooklyn/master/README.md", Urls.mergePaths(dest.getAbsolutePath(), "README.md"));
+            assertEquals(result, 0);
+            String contents = ArchiveUtils.readFullyString(new File(dest, "README.md"));
+            assertTrue(contents.contains("http://brooklyncentral.github.com"), "contents missing expected phrase; contains:\n"+contents);
+        } finally {
+            dest.delete();
+        }
+    }
+    
+    @Test(groups = "Integration")
+    public void testInstallClasspathCopyTo() throws Exception {
+        File dest = new File(Os.tmp(), "sshMachineLocationTest_dir/");
+        dest.mkdir();
+        try {
+            int result = host.installTo("classpath://brooklyn/config/sample.properties", Urls.mergePaths(dest.getAbsolutePath(), "sample.properties"));
+            assertEquals(result, 0);
+            String contents = ArchiveUtils.readFullyString(new File(dest, "sample.properties"));
+            assertTrue(contents.contains("Property 1"), "contents missing expected phrase; contains:\n"+contents);
+        } finally {
+            dest.delete();
+        }
+    }
+
+    // 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.
+    //
+    // Times out in 2m7s on Ubuntu Vivid (syn retries set to 6)
+    @Test(groups = "Integration")
+    public void testIsSshableWhenFalse() throws Exception {
+        byte[] unreachableIp = new byte[] {123,123,123,123};
+        final SshMachineLocation unreachableHost = new SshMachineLocation(MutableMap.of("address", InetAddress.getByAddress("unreachablename", unreachableIp)));
+        Asserts.assertReturnsEventually(new Runnable() {
+            public void run() {
+                assertFalse(unreachableHost.isSshable());
+            }},
+            Duration.minutes(3));
+    }
+
+    // For issue #230
+    @Test(groups = "Integration")
+    public void testOverridingPropertyOnExec() throws Exception {
+        SshMachineLocation host = new SshMachineLocation(MutableMap.of("address", Networking.getLocalHost(), "sshPrivateKeyData", "wrongdata"));
+        
+        OutputStream outStream = new ByteArrayOutputStream();
+        String expectedName = Os.user();
+        host.execCommands(MutableMap.of("sshPrivateKeyData", null, "out", outStream), "my summary", ImmutableList.of("whoami"));
+        String outString = outStream.toString();
+        
+        assertTrue(outString.contains(expectedName), "outString="+outString);
+    }
+
+    @Test(groups = "Integration", expectedExceptions={IllegalStateException.class, SshException.class})
+    public void testSshRunWithInvalidUserFails() throws Exception {
+        SshMachineLocation badHost = new SshMachineLocation(MutableMap.of("user", "doesnotexist", "address", Networking.getLocalHost()));
+        badHost.execScript("mysummary", ImmutableList.of("whoami; exit"));
+    }
+    
     // Note: requires `named:localhost-passphrase` set up with a key whose passphrase is "localhost"
     // * create the key with:
     //      ssh-keygen -t rsa -N "brooklyn" -f ~/.ssh/id_rsa_passphrase

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/e5b40cc1/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationTest.java b/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationTest.java
index 2c7a78d..c09d790 100644
--- a/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationTest.java
@@ -26,9 +26,7 @@ import static org.testng.Assert.assertSame;
 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;
@@ -45,9 +43,9 @@ import org.apache.brooklyn.api.location.PortRange;
 import org.apache.brooklyn.core.effector.EffectorBody;
 import org.apache.brooklyn.core.effector.EffectorTaskTest;
 import org.apache.brooklyn.core.effector.Effectors;
+import org.apache.brooklyn.core.entity.AbstractEntity;
 import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
 import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.core.entity.factory.ApplicationBuilder;
 import org.apache.brooklyn.core.location.BasicHardwareDetails;
 import org.apache.brooklyn.core.location.BasicMachineDetails;
 import org.apache.brooklyn.core.location.BasicOsDetails;
@@ -55,42 +53,40 @@ import org.apache.brooklyn.core.location.Machines;
 import org.apache.brooklyn.core.location.PortRanges;
 import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
 import org.apache.brooklyn.core.test.entity.TestApplication;
-import org.apache.brooklyn.test.Asserts;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.core.file.ArchiveUtils;
 import org.apache.brooklyn.util.core.internal.ssh.RecordingSshTool;
-import org.apache.brooklyn.util.core.internal.ssh.SshException;
+import org.apache.brooklyn.util.core.internal.ssh.RecordingSshTool.CustomResponse;
 import org.apache.brooklyn.util.core.task.BasicExecutionContext;
 import org.apache.brooklyn.util.core.task.BasicExecutionManager;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.net.Networking;
-import org.apache.brooklyn.util.net.Urls;
 import org.apache.brooklyn.util.os.Os;
 import org.apache.brooklyn.util.stream.Streams;
-import org.apache.brooklyn.util.time.Duration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-import com.google.common.base.Charsets;
+import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
-import com.google.common.io.Files;
 
 /**
  * Test the {@link SshMachineLocation} implementation of the {@link Location} interface.
  */
 public class SshMachineLocationTest extends BrooklynAppUnitTestSupport {
 
-    private SshMachineLocation host;
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractEntity.class);
+
+    protected SshMachineLocation host;
     
     @BeforeMethod(alwaysRun=true)
     public void setUp() throws Exception {
         super.setUp();
-        host = mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
-                .configure("address", Networking.getLocalHost()));
+        host = newHost();
         RecordingSshTool.clear();
     }
 
@@ -104,8 +100,22 @@ public class SshMachineLocationTest extends BrooklynAppUnitTestSupport {
         }
     }
 
-    @Test(groups = "Integration")
+    protected SshMachineLocation newHost() {
+        return mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
+                .configure("address", Networking.getLocalHost())
+                .configure(SshMachineLocation.SSH_TOOL_CLASS, RecordingSshTool.class.getName()));
+    }
+    
+    @Test
     public void testGetMachineDetails() throws Exception {
+        String response = Joiner.on("\n").join(
+                "name:Test OS Y",
+                "version:1.2.3",
+                "architecture:x86_64",
+                "ram:1234",
+                "cpus:3");
+        RecordingSshTool.setCustomResponse(".*uname.*", new CustomResponse(0, response, ""));
+
         BasicExecutionManager execManager = new BasicExecutionManager("mycontextid");
         BasicExecutionContext execContext = new BasicExecutionContext(execManager);
         try {
@@ -113,12 +123,19 @@ public class SshMachineLocationTest extends BrooklynAppUnitTestSupport {
                 public MachineDetails call() {
                     return host.getMachineDetails();
                 }}).get();
+            LOG.info("machineDetails="+details);
             assertNotNull(details);
+            
+            assertEquals(details.getOsDetails().getName(), "Test OS Y", "details="+details);
+            assertEquals(details.getOsDetails().getVersion(), "1.2.3", "details="+details);
+            assertEquals(details.getOsDetails().getArch(), "x86_64", "details="+details);
+            assertEquals(details.getHardwareDetails().getCpuCount(), Integer.valueOf(3), "details="+details);
+            assertEquals(details.getHardwareDetails().getRam(), Integer.valueOf(1234), "details="+details);
         } finally {
             execManager.shutdownNow();
         }
     }
-    
+
     @Test
     public void testSupplyingMachineDetails() throws Exception {
         MachineDetails machineDetails = new BasicMachineDetails(new BasicHardwareDetails(1, 1024), new BasicOsDetails("myname", "myarch", "myversion"));
@@ -136,12 +153,14 @@ public class SshMachineLocationTest extends BrooklynAppUnitTestSupport {
                 .configure(BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, true));
 
         assertEquals(host2.getPrivateAddresses(), ImmutableSet.of("1.2.3.4"));
+        assertEquals(Machines.getSubnetIp(host2).get(), "1.2.3.4");
+        assertEquals(Machines.getSubnetHostname(host2).get(), "1.2.3.4");
     }
     
     // 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")
+    @Test
     public void testGetMachineIsInessentialOnFailure() throws Exception {
         SshMachineLocation host2 = mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
                 .configure("address", Networking.getLocalHost())
@@ -167,7 +186,7 @@ public class SshMachineLocationTest extends BrooklynAppUnitTestSupport {
                             ((EntityInternal)entity).getMutableEntityType().addEffector(EffectorTaskTest.DOUBLE_1);
                         }});
 
-        TestApplication app = ApplicationBuilder.newManagedApp(appSpec, mgmt);
+        TestApplication app = mgmt.getEntityManager().createEntity(appSpec);
 
         app.start(ImmutableList.of(host2));
         
@@ -186,124 +205,35 @@ public class SshMachineLocationTest extends BrooklynAppUnitTestSupport {
         }
     }
     
-    // Note: requires `ssh localhost` to be setup such that no password is required    
-    @Test(groups = "Integration")
+    @Test
     public void testSshExecScript() throws Exception {
-        OutputStream outStream = new ByteArrayOutputStream();
         String expectedName = Os.user();
+        RecordingSshTool.setCustomResponse(".*whoami.*", new CustomResponse(0, expectedName, ""));
+        
+        OutputStream outStream = new ByteArrayOutputStream();
         host.execScript(MutableMap.of("out", outStream), "mysummary", ImmutableList.of("whoami; exit"));
         String outString = outStream.toString();
         
         assertTrue(outString.contains(expectedName), outString);
     }
     
-    // Note: requires `ssh localhost` to be setup such that no password is required    
-    @Test(groups = "Integration")
+    @Test
     public void testSshExecCommands() throws Exception {
-        OutputStream outStream = new ByteArrayOutputStream();
         String expectedName = Os.user();
-        host.execCommands(MutableMap.of("out", outStream), "mysummary", ImmutableList.of("whoami; exit"));
-        String outString = outStream.toString();
-        
-        assertTrue(outString.contains(expectedName), outString);
-    }
-    
-    // For issue #230
-    @Test(groups = "Integration")
-    public void testOverridingPropertyOnExec() throws Exception {
-        SshMachineLocation host = new SshMachineLocation(MutableMap.of("address", Networking.getLocalHost(), "sshPrivateKeyData", "wrongdata"));
+        RecordingSshTool.setCustomResponse(".*whoami.*", new CustomResponse(0, expectedName, ""));
         
         OutputStream outStream = new ByteArrayOutputStream();
-        String expectedName = Os.user();
-        host.execCommands(MutableMap.of("sshPrivateKeyData", null, "out", outStream), "my summary", ImmutableList.of("whoami"));
+        host.execCommands(MutableMap.of("out", outStream), "mysummary", ImmutableList.of("whoami; exit"));
         String outString = outStream.toString();
         
-        assertTrue(outString.contains(expectedName), "outString="+outString);
-    }
-
-    @Test(groups = "Integration", expectedExceptions={IllegalStateException.class, SshException.class})
-    public void testSshRunWithInvalidUserFails() throws Exception {
-        SshMachineLocation badHost = new SshMachineLocation(MutableMap.of("user", "doesnotexist", "address", Networking.getLocalHost()));
-        badHost.execScript("mysummary", ImmutableList.of("whoami; exit"));
-    }
-    
-    // Note: requires `ssh localhost` to be setup such that no password is required    
-    @Test(groups = "Integration")
-    public void testCopyFileTo() throws Exception {
-        File dest = Os.newTempFile(getClass(), ".dest.tmp");
-        File src = Os.newTempFile(getClass(), ".src.tmp");
-        try {
-            Files.write("abc", src, Charsets.UTF_8);
-            host.copyTo(src, dest);
-            assertEquals("abc", Files.readFirstLine(dest, Charsets.UTF_8));
-        } finally {
-            src.delete();
-            dest.delete();
-        }
-    }
-
-    // Note: requires `ssh localhost` to be setup such that no password is required    
-    @Test(groups = "Integration")
-    public void testCopyStreamTo() throws Exception {
-        String contents = "abc";
-        File dest = new File(Os.tmp(), "sshMachineLocationTest_dest.tmp");
-        try {
-            host.copyTo(Streams.newInputStreamWithContents(contents), dest.getAbsolutePath());
-            assertEquals("abc", Files.readFirstLine(dest, Charsets.UTF_8));
-        } finally {
-            dest.delete();
-        }
-    }
-
-    @Test(groups = "Integration")
-    public void testInstallUrlTo() throws Exception {
-        File dest = new File(Os.tmp(), "sshMachineLocationTest_dir/");
-        dest.mkdir();
-        try {
-            int result = host.installTo("https://raw.github.com/brooklyncentral/brooklyn/master/README.md", Urls.mergePaths(dest.getAbsolutePath(), "README.md"));
-            assertEquals(result, 0);
-            String contents = ArchiveUtils.readFullyString(new File(dest, "README.md"));
-            assertTrue(contents.contains("http://brooklyncentral.github.com"), "contents missing expected phrase; contains:\n"+contents);
-        } finally {
-            dest.delete();
-        }
+        assertTrue(outString.contains(expectedName), outString);
     }
     
-    @Test(groups = "Integration")
-    public void testInstallClasspathCopyTo() throws Exception {
-        File dest = new File(Os.tmp(), "sshMachineLocationTest_dir/");
-        dest.mkdir();
-        try {
-            int result = host.installTo("classpath://brooklyn/config/sample.properties", Urls.mergePaths(dest.getAbsolutePath(), "sample.properties"));
-            assertEquals(result, 0);
-            String contents = ArchiveUtils.readFullyString(new File(dest, "sample.properties"));
-            assertTrue(contents.contains("Property 1"), "contents missing expected phrase; contains:\n"+contents);
-        } finally {
-            dest.delete();
-        }
-    }
-
-    // Note: requires `ssh localhost` to be setup such that no password is required    
-    @Test(groups = "Integration")
+    @Test
     public void testIsSshableWhenTrue() throws Exception {
         assertTrue(host.isSshable());
     }
     
-    // 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.
-    //
-    // Times out in 2m7s on Ubuntu Vivid (syn retries set to 6)
-    @Test(groups = "Integration")
-    public void testIsSshableWhenFalse() throws Exception {
-        byte[] unreachableIp = new byte[] {123,123,123,123};
-        final SshMachineLocation unreachableHost = new SshMachineLocation(MutableMap.of("address", InetAddress.getByAddress("unreachablename", unreachableIp)));
-        Asserts.assertReturnsEventually(new Runnable() {
-            public void run() {
-                assertFalse(unreachableHost.isSshable());
-            }},
-            Duration.minutes(3));
-    }
-    
     @Test
     public void obtainSpecificPortGivesOutPortOnlyOnce() {
         int port = 2345;


[3/4] brooklyn-server git commit: SshMachineLocationIntegrationTest: change unreachable ip

Posted by gr...@apache.org.
SshMachineLocationIntegrationTest: change unreachable ip

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

Branch: refs/heads/master
Commit: 33dd48c2d2ae743756e68b94ad5099f098cf1014
Parents: 171843e
Author: Aled Sage <al...@gmail.com>
Authored: Thu Dec 1 15:52:34 2016 +0000
Committer: Aled Sage <al...@gmail.com>
Committed: Thu Dec 1 15:52:34 2016 +0000

----------------------------------------------------------------------
 .../ssh/SshMachineLocationIntegrationTest.java        | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/33dd48c2/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationIntegrationTest.java
index 081d0a8..d0214fd 100644
--- a/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationIntegrationTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationIntegrationTest.java
@@ -185,14 +185,18 @@ public class SshMachineLocationIntegrationTest extends SshMachineLocationTest {
         }
     }
 
-    // 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.
+    // See http://superuser.com/a/698251/497648 for choice of unreachable IP.
+    // Even with 240.0.0.0, it takes a long time (75 seconds in office network).
+    //
+    // Previously, "123.123.123.123" would seemingly hang on some (home/airport) networks.
+    // Times out (with 123.123.123.123) in 2m7s on Ubuntu Vivid (syn retries set to 6)
     //
-    // Times out in 2m7s on Ubuntu Vivid (syn retries set to 6)
+    // 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};
-        final SshMachineLocation unreachableHost = new SshMachineLocation(MutableMap.of("address", InetAddress.getByAddress("unreachablename", unreachableIp)));
+        String unreachableIp = "240.0.0.0";
+        final SshMachineLocation unreachableHost = new SshMachineLocation(MutableMap.of("address", InetAddress.getByName(unreachableIp)));
+        System.out.println(unreachableHost.getAddress());
         Asserts.assertReturnsEventually(new Runnable() {
             public void run() {
                 assertFalse(unreachableHost.isSshable());


[4/4] brooklyn-server git commit: This closes #475

Posted by gr...@apache.org.
This closes #475

* github/pr/475:
  SshMachineLocationIntegrationTest: change unreachable ip
  BROOKLYN-405: ssh doesn't log password environment variables
  SshMachineLocationTest: make non-integration


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

Branch: refs/heads/master
Commit: 615c635748a45e79b81e583f4f475527f244fc48
Parents: 50826cb 33dd48c
Author: Andrew Donald Kennedy <an...@cloudsoftcorp.com>
Authored: Thu Dec 1 16:03:11 2016 +0000
Committer: Andrew Donald Kennedy <an...@cloudsoftcorp.com>
Committed: Thu Dec 1 16:03:11 2016 +0000

----------------------------------------------------------------------
 .../location/ssh/SshMachineLocation.java        |   1 -
 .../system/internal/ExecWithLoggingHelpers.java |   3 +-
 .../ssh/SshMachineLocationIntegrationTest.java  | 195 +++++++++++++++++--
 .../location/ssh/SshMachineLocationTest.java    | 194 ++++++++----------
 .../org/apache/brooklyn/test/LogWatcher.java    |  36 +++-
 5 files changed, 283 insertions(+), 146 deletions(-)
----------------------------------------------------------------------



[2/4] brooklyn-server git commit: BROOKLYN-405: ssh doesn't log password environment variables

Posted by gr...@apache.org.
BROOKLYN-405: ssh doesn't log password environment variables


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

Branch: refs/heads/master
Commit: 171843ecef4b5432c91840de15399bf7aa42fed9
Parents: e5b40cc
Author: Aled Sage <al...@gmail.com>
Authored: Thu Dec 1 08:50:22 2016 +0000
Committer: Aled Sage <al...@gmail.com>
Committed: Thu Dec 1 15:38:53 2016 +0000

----------------------------------------------------------------------
 .../location/ssh/SshMachineLocation.java        |  1 -
 .../system/internal/ExecWithLoggingHelpers.java |  3 +-
 .../ssh/SshMachineLocationIntegrationTest.java  |  7 ++++
 .../location/ssh/SshMachineLocationTest.java    | 34 ++++++++++++++++++
 .../org/apache/brooklyn/test/LogWatcher.java    | 36 ++++++++++++++------
 5 files changed, 69 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/171843ec/core/src/main/java/org/apache/brooklyn/location/ssh/SshMachineLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/ssh/SshMachineLocation.java b/core/src/main/java/org/apache/brooklyn/location/ssh/SshMachineLocation.java
index 40ce7a6..b611c3c 100644
--- a/core/src/main/java/org/apache/brooklyn/location/ssh/SshMachineLocation.java
+++ b/core/src/main/java/org/apache/brooklyn/location/ssh/SshMachineLocation.java
@@ -30,7 +30,6 @@ import java.io.OutputStream;
 import java.io.PipedInputStream;
 import java.io.PipedOutputStream;
 import java.io.Reader;
-import java.io.StringReader;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.Socket;

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/171843ec/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/ExecWithLoggingHelpers.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/ExecWithLoggingHelpers.java b/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/ExecWithLoggingHelpers.java
index e96dce9..790dc18 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/ExecWithLoggingHelpers.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/ExecWithLoggingHelpers.java
@@ -27,6 +27,7 @@ import java.util.Map;
 
 import org.slf4j.Logger;
 import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.Sanitizer;
 import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.config.ConfigBag;
@@ -112,7 +113,7 @@ public abstract class ExecWithLoggingHelpers {
             String allcmds = (Strings.isBlank(expectedCommandHeaders) ? "" : expectedCommandHeaders + " ; ") + Strings.join(commands, " ; ");
             commandLogger.debug("{}, initiating "+shortName.toLowerCase()+" on machine {}{}: {}",
                     new Object[] {summaryForLogging, getTargetName(),
-                    env!=null && !env.isEmpty() ? " (env "+env+")": "", allcmds});
+                    env!=null && !env.isEmpty() ? " (env "+Sanitizer.sanitize(env)+")": "", allcmds});
         }
 
         if (commands.isEmpty()) {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/171843ec/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationIntegrationTest.java
index 1def66f..081d0a8 100644
--- a/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationIntegrationTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationIntegrationTest.java
@@ -103,6 +103,13 @@ public class SshMachineLocationIntegrationTest extends SshMachineLocationTest {
         super.testIsSshableWhenTrue();
     }
 
+    // Overridden just to make it integration (because `newHost()` returns a real ssh'ing host)
+    @Test(groups="Integration")
+    @Override
+    public void testDoesNotLogPasswordsInEnvironmentVariables() {
+        super.testDoesNotLogPasswordsInEnvironmentVariables();
+    }
+
     // Overrides super, because expect real machine details (rather than asserting our stub data)
     @Test(groups = "Integration")
     @Override

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/171843ec/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationTest.java b/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationTest.java
index c09d790..3b6239c 100644
--- a/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationTest.java
@@ -40,6 +40,7 @@ import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.location.MachineDetails;
 import org.apache.brooklyn.api.location.MachineLocation;
 import org.apache.brooklyn.api.location.PortRange;
+import org.apache.brooklyn.core.BrooklynLogging;
 import org.apache.brooklyn.core.effector.EffectorBody;
 import org.apache.brooklyn.core.effector.EffectorTaskTest;
 import org.apache.brooklyn.core.effector.Effectors;
@@ -53,10 +54,13 @@ import org.apache.brooklyn.core.location.Machines;
 import org.apache.brooklyn.core.location.PortRanges;
 import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
 import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.test.LogWatcher;
+import org.apache.brooklyn.test.LogWatcher.EventPredicates;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.internal.ssh.RecordingSshTool;
 import org.apache.brooklyn.util.core.internal.ssh.RecordingSshTool.CustomResponse;
+import org.apache.brooklyn.util.core.internal.ssh.sshj.SshjTool;
 import org.apache.brooklyn.util.core.task.BasicExecutionContext;
 import org.apache.brooklyn.util.core.task.BasicExecutionManager;
 import org.apache.brooklyn.util.guava.Maybe;
@@ -70,9 +74,15 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import com.google.common.base.Joiner;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+
+import ch.qos.logback.classic.spi.ILoggingEvent;
 
 /**
  * Test the {@link SshMachineLocation} implementation of the {@link Location} interface.
@@ -273,4 +283,28 @@ public class SshMachineLocationTest extends BrooklynAppUnitTestSupport {
         assertEquals(host.obtainPort(PortRanges.fromString("8000")), -1);
         assertEquals(host.obtainPort(PortRanges.fromString("8000+")), 8001);
     }
+    
+    @Test
+    public void testDoesNotLogPasswordsInEnvironmentVariables() {
+        List<String> loggerNames = ImmutableList.of(
+                SshMachineLocation.class.getName(), 
+                BrooklynLogging.SSH_IO, 
+                SshjTool.class.getName());
+        ch.qos.logback.classic.Level logLevel = ch.qos.logback.classic.Level.DEBUG;
+        Predicate<ILoggingEvent> filter = Predicates.or(
+                EventPredicates.containsMessage("DB_PASSWORD"), 
+                EventPredicates.containsMessage("mypassword"));
+        LogWatcher watcher = new LogWatcher(loggerNames, logLevel, filter);
+
+        watcher.start();
+        try {
+            host.execCommands("mySummary", ImmutableList.of("true"), ImmutableMap.of("DB_PASSWORD", "mypassword"));
+            watcher.assertHasEventEventually();
+            
+            Optional<ILoggingEvent> eventWithPasswd = Iterables.tryFind(watcher.getEvents(), EventPredicates.containsMessage("mypassword"));
+            assertFalse(eventWithPasswd.isPresent(), "event="+eventWithPasswd);
+        } finally {
+            watcher.close();
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/171843ec/test-support/src/main/java/org/apache/brooklyn/test/LogWatcher.java
----------------------------------------------------------------------
diff --git a/test-support/src/main/java/org/apache/brooklyn/test/LogWatcher.java b/test-support/src/main/java/org/apache/brooklyn/test/LogWatcher.java
index 6baa852..6495db3 100644
--- a/test-support/src/main/java/org/apache/brooklyn/test/LogWatcher.java
+++ b/test-support/src/main/java/org/apache/brooklyn/test/LogWatcher.java
@@ -25,6 +25,7 @@ import static org.testng.Assert.assertFalse;
 import java.io.Closeable;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.mockito.Mockito;
@@ -37,6 +38,7 @@ import com.google.common.annotations.Beta;
 import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
 
 import ch.qos.logback.classic.Level;
 import ch.qos.logback.classic.spi.ILoggingEvent;
@@ -88,13 +90,20 @@ public class LogWatcher implements Closeable {
     private final List<ILoggingEvent> events = Collections.synchronizedList(Lists.<ILoggingEvent>newLinkedList());
     private final AtomicBoolean closed = new AtomicBoolean();
     private final ch.qos.logback.classic.Level loggerLevel;
-    private final ch.qos.logback.classic.Logger watchedLogger;
     private final Appender<ILoggingEvent> appender;
-    private volatile Level origLevel;
+    private final List<ch.qos.logback.classic.Logger> watchedLoggers = Lists.newArrayList();
+    private volatile Map<ch.qos.logback.classic.Logger, Level> origLevels = Maps.newLinkedHashMap();
+
+    public LogWatcher(String loggerName, ch.qos.logback.classic.Level loggerLevel, final Predicate<? super ILoggingEvent> filter) {
+        this(ImmutableList.of(checkNotNull(loggerName, "loggerName")), loggerLevel, filter);
+    }
     
     @SuppressWarnings("unchecked")
-    public LogWatcher(String loggerName, ch.qos.logback.classic.Level loggerLevel, final Predicate<? super ILoggingEvent> filter) {
-        this.watchedLogger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(checkNotNull(loggerName, "loggerName"));
+    public LogWatcher(Iterable<String> loggerNames, ch.qos.logback.classic.Level loggerLevel, final Predicate<? super ILoggingEvent> filter) {
+        for (String loggerName : loggerNames) {
+            Logger logger = LoggerFactory.getLogger(checkNotNull(loggerName, "loggerName"));
+            watchedLoggers.add((ch.qos.logback.classic.Logger) logger);
+        }
         this.loggerLevel = checkNotNull(loggerLevel, "loggerLevel");
         this.appender = Mockito.mock(Appender.class);
         
@@ -115,18 +124,25 @@ public class LogWatcher implements Closeable {
     
     public void start() {
         checkState(!closed.get(), "Cannot start LogWatcher after closed");
-        origLevel = watchedLogger.getLevel();
-        watchedLogger.setLevel(loggerLevel);
-        watchedLogger.addAppender(appender);
+        for (ch.qos.logback.classic.Logger watchedLogger : watchedLoggers) {
+            origLevels.put(watchedLogger, watchedLogger.getLevel());
+            watchedLogger.setLevel(loggerLevel);
+            watchedLogger.addAppender(appender);
+        }
     }
     
     @Override
     public void close() {
         if (closed.compareAndSet(false, true)) {
-            if (watchedLogger != null) {
-                if (origLevel != null) watchedLogger.setLevel(origLevel);
-                watchedLogger.detachAppender(appender);
+            if (watchedLoggers != null) {
+                for (ch.qos.logback.classic.Logger watchedLogger : watchedLoggers) {
+                    Level origLevel = origLevels.get(watchedLogger);
+                    if (origLevel != null) watchedLogger.setLevel(origLevel);
+                    watchedLogger.detachAppender(appender);
+                }
             }
+            watchedLoggers.clear();
+            origLevels.clear();
         }
     }