Skip to content

Commit

Permalink
Merge pull request #122 from gdgib/G2-1546-PortForward
Browse files Browse the repository at this point in the history
G2-1546 Test SSH w/port forwarding  @gdgib gdgib committed 2 minutes ago
  • Loading branch information
gdgib authored Mar 1, 2024
2 parents eb781db + ac3ed20 commit 4e05aea
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 47 deletions.
50 changes: 50 additions & 0 deletions gb-ssh/src/test/java/com/g2forge/gearbox/ssh/TestSSH.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.g2forge.gearbox.ssh;

import java.time.Duration;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import com.g2forge.alexandria.wizard.InputUnspecifiedException;
import com.g2forge.alexandria.wizard.PropertyStringInput;
import com.g2forge.alexandria.wizard.UserPasswordInput;
import com.g2forge.alexandria.wizard.UserStringInput;

import lombok.Getter;

public class TestSSH {
@Getter(lazy = true)
private static final SSHConfig config = createConfig();

protected static SSHConfig createConfig() {
final ExecutorService executor = Executors.newSingleThreadExecutor();
final Future<SSHConfig> handler = executor.submit(new Callable<SSHConfig>() {
@Override
public SSHConfig call() throws Exception {
try {
final SSHRemote.SSHRemoteBuilder remote = SSHRemote.builder();
final SSHCredentials.SSHCredentialsBuilder credentials = SSHCredentials.builder();
remote.username(new PropertyStringInput("ssh.username").fallback(new UserStringInput("SSH Username", false)).get());
credentials.password(new PropertyStringInput("ssh.password").fallback(new UserPasswordInput("SSH Password")).get());
remote.host(new PropertyStringInput("ssh.host").fallback(new UserStringInput("SSH Host", false)).get());
remote.port(Integer.valueOf(new PropertyStringInput("ssh.port").fallback(new UserStringInput("SSH Port", false)).get()));
return new SSHConfig(remote.build(), credentials.build());
} catch (InputUnspecifiedException exception) {
return null;
}
}
});
try {
return handler.get(Duration.ofSeconds(60).toMillis(), TimeUnit.MILLISECONDS);
} catch (TimeoutException | InterruptedException | ExecutionException exception) {
handler.cancel(true);
return null;
} finally {
executor.shutdownNow();
}
}
}
38 changes: 38 additions & 0 deletions gb-ssh/src/test/java/com/g2forge/gearbox/ssh/TestSSHProxy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.g2forge.gearbox.ssh;

import java.io.IOException;

import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.client.session.forward.ExplicitPortForwardingTracker;
import org.apache.sshd.common.util.net.SshdSocketAddress;
import org.junit.Test;

import com.g2forge.alexandria.test.HAssert;
import com.g2forge.alexandria.test.HAssume;
import com.g2forge.gearbox.command.IUtils;
import com.g2forge.gearbox.command.converter.dumb.DumbCommandConverter;
import com.g2forge.gearbox.command.proxy.CommandProxyFactory;

public class TestSSHProxy {
@Test
public void proxy() {
final SSHConfig config = TestSSH.getConfig();
HAssume.assumeNotNull(config);
try (final SshClient client = SshClient.setUpDefaultClient()) {
client.start();
try (final ClientSession session = config.connect(client)) {
final ExplicitPortForwardingTracker tunnel = session.createLocalPortForwardingTracker(0, new SshdSocketAddress(config.getRemote().getPort()));;

final SSHConfig proxyConfig = new SSHConfig(new SSHRemote(config.getRemote().getUsername(), "localhost", tunnel.getBoundAddress().getPort()), config.getCredentials());
final String message = "Test message";
try (final SSHRunner runner = new SSHRunner(client, proxyConfig)) {
final String actual = new CommandProxyFactory(new DumbCommandConverter(), runner).apply(IUtils.class).echo(false, message);
HAssert.assertEquals(message, actual.stripTrailing());
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
51 changes: 4 additions & 47 deletions gb-ssh/src/test/java/com/g2forge/gearbox/ssh/TestSSHRunner.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
package com.g2forge.gearbox.ssh;

import java.nio.file.Paths;
import java.time.Duration;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.After;
import org.junit.Test;
Expand All @@ -18,50 +10,15 @@
import com.g2forge.alexandria.java.function.IFunction1;
import com.g2forge.alexandria.test.HAssert;
import com.g2forge.alexandria.test.HAssume;
import com.g2forge.alexandria.wizard.InputUnspecifiedException;
import com.g2forge.alexandria.wizard.PropertyStringInput;
import com.g2forge.alexandria.wizard.UserPasswordInput;
import com.g2forge.alexandria.wizard.UserStringInput;
import com.g2forge.gearbox.command.converter.ICommandConverterR_;
import com.g2forge.gearbox.command.converter.dumb.DumbCommandConverter;
import com.g2forge.gearbox.command.process.IProcess;
import com.g2forge.gearbox.command.process.redirect.IRedirect;
import com.g2forge.gearbox.command.test.ATestCommand;

import lombok.Getter;

public class TestSSHRunner extends ATestCommand {
@Getter(lazy = true)
private static final SSHConfig config = createConfig();

protected static SSHConfig createConfig() {
final ExecutorService executor = Executors.newSingleThreadExecutor();
final Future<SSHConfig> handler = executor.submit(new Callable<SSHConfig>() {
@Override
public SSHConfig call() throws Exception {
try {
final SSHRemote.SSHRemoteBuilder remote = SSHRemote.builder();
final SSHCredentials.SSHCredentialsBuilder credentials = SSHCredentials.builder();
remote.username(new PropertyStringInput("ssh.username").fallback(new UserStringInput("SSH Username", false)).get());
credentials.password(new PropertyStringInput("ssh.password").fallback(new UserPasswordInput("SSH Password")).get());
remote.host(new PropertyStringInput("ssh.host").fallback(new UserStringInput("SSH Host", false)).get());
remote.port(Integer.valueOf(new PropertyStringInput("ssh.port").fallback(new UserStringInput("SSH Port", false)).get()));
return new SSHConfig(remote.build(), credentials.build());
} catch (InputUnspecifiedException exception) {
return null;
}
}
});
try {
return handler.get(Duration.ofSeconds(60).toMillis(), TimeUnit.MILLISECONDS);
} catch (TimeoutException | InterruptedException | ExecutionException exception) {
handler.cancel(true);
return null;
} finally {
executor.shutdownNow();
}
}

@After
public void close() {
final Object runner;
Expand All @@ -80,24 +37,24 @@ protected ICommandConverterR_ createRenderer() {

@Override
protected IFunction1<CommandInvocation<IRedirect, IRedirect>, IProcess> createRunner() {
return new SSHRunner(getConfig());
return new SSHRunner(TestSSH.getConfig());
}

@Test
public void cwd() {
HAssume.assumeNotNull(getConfig());
HAssume.assumeNotNull(TestSSH.getConfig());
final String cwd = HAssume.assumeNoException(new PropertyStringInput("sshtest.cwd").fallback(new UserStringInput("SSH Test CWD", false)));
HAssert.assertEquals(cwd, getUtils().pwd(Paths.get("./"), false).trim());
}

@Test
public void hostname() {
HAssume.assumeNotNull(getConfig());
HAssume.assumeNotNull(TestSSH.getConfig());
final String hostname = HAssume.assumeNoException(new PropertyStringInput("sshtest.hostname").fallback(new UserStringInput("SSH Test Hostname", false)));
HAssert.assertEquals(hostname, getUtils().echo(false, "${HOSTNAME}").trim());
}

protected boolean isValid() {
return getConfig() != null;
return TestSSH.getConfig() != null;
}
}

0 comments on commit 4e05aea

Please sign in to comment.