Use testcontainers (#741)

* Replace abstract class IntegrationBaseSpec with composition through IntegrationTestUtil

* Switch to testcontainers in integration tests

It allows running different SSH servers with different configurations in tests, giving ability to cover more bugs, like mentioned in #733.
This commit is contained in:
Vladimir Lagunov
2021-11-10 20:30:35 +07:00
committed by GitHub
parent 8a66dc5336
commit d5805a6c64
14 changed files with 280 additions and 151 deletions

View File

@@ -1,7 +1,3 @@
import java.text.SimpleDateFormat
import com.bmuschko.gradle.docker.tasks.container.*
import com.bmuschko.gradle.docker.tasks.image.*
plugins { plugins {
id "java" id "java"
id "groovy" id "groovy"
@@ -60,7 +56,7 @@ dependencies {
testRuntimeOnly "ch.qos.logback:logback-classic:1.2.6" testRuntimeOnly "ch.qos.logback:logback-classic:1.2.6"
testImplementation 'org.glassfish.grizzly:grizzly-http-server:2.4.4' testImplementation 'org.glassfish.grizzly:grizzly-http-server:2.4.4'
testImplementation 'org.apache.httpcomponents:httpclient:4.5.9' testImplementation 'org.apache.httpcomponents:httpclient:4.5.9'
testImplementation 'org.testcontainers:testcontainers:1.16.2'
} }
license { license {
@@ -276,48 +272,11 @@ jacocoTestReport {
} }
} }
task buildItestImage(type: DockerBuildImage) {
inputDir = file('src/itest/docker-image')
images.add('sshj/sshd-itest:latest')
}
task createItestContainer(type: DockerCreateContainer) {
dependsOn buildItestImage
targetImageId buildItestImage.getImageId()
hostConfig.portBindings = ['2222:22']
hostConfig.autoRemove = true
}
task startItestContainer(type: DockerStartContainer) {
dependsOn createItestContainer
targetContainerId createItestContainer.getContainerId()
}
task logItestContainer(type: DockerLogsContainer) {
dependsOn createItestContainer
targetContainerId createItestContainer.getContainerId()
showTimestamps = true
stdErr = true
stdOut = true
tailAll = true
}
task stopItestContainer(type: DockerStopContainer) {
targetContainerId createItestContainer.getContainerId()
}
task forkedUploadRelease(type: GradleBuild) { task forkedUploadRelease(type: GradleBuild) {
buildFile = project.buildFile buildFile = project.buildFile
tasks = ["clean", "publishToSonatype", "closeAndReleaseSonatypeStagingRepository"] tasks = ["clean", "publishToSonatype", "closeAndReleaseSonatypeStagingRepository"]
} }
project.tasks.integrationTest.dependsOn(startItestContainer)
project.tasks.integrationTest.finalizedBy(stopItestContainer)
// Being enabled, it pollutes logs on CI. Uncomment when debugging some test to get sshd logs.
// project.tasks.stopItestContainer.dependsOn(logItestContainer)
project.tasks.release.dependsOn([project.tasks.integrationTest, project.tasks.build]) project.tasks.release.dependsOn([project.tasks.integrationTest, project.tasks.build])
project.tasks.release.finalizedBy(project.tasks.forkedUploadRelease) project.tasks.release.finalizedBy(project.tasks.forkedUploadRelease)
project.tasks.jacocoTestReport.dependsOn(project.tasks.test) project.tasks.jacocoTestReport.dependsOn(project.tasks.test)

View File

@@ -1,24 +0,0 @@
FROM sickp/alpine-sshd:7.5-r2
ADD authorized_keys /home/sshj/.ssh/authorized_keys
ADD test-container/ssh_host_ecdsa_key /etc/ssh/ssh_host_ecdsa_key
ADD test-container/ssh_host_ecdsa_key.pub /etc/ssh/ssh_host_ecdsa_key.pub
ADD test-container/ssh_host_ed25519_key /etc/ssh/ssh_host_ed25519_key
ADD test-container/ssh_host_ed25519_key.pub /etc/ssh/ssh_host_ed25519_key.pub
ADD test-container/sshd_config /etc/ssh/sshd_config
COPY test-container/trusted_ca_keys /etc/ssh/trusted_ca_keys
COPY test-container/host_keys/* /etc/ssh/
RUN apk add --no-cache tini
RUN \
echo "root:smile" | chpasswd && \
adduser -D -s /bin/ash sshj && \
passwd -u sshj && \
echo "sshj:ultrapassword" | chpasswd && \
chmod 600 /home/sshj/.ssh/authorized_keys && \
chmod 600 /etc/ssh/ssh_host_*_key && \
chmod 644 /etc/ssh/*.pub && \
chown -R sshj:sshj /home/sshj
ENTRYPOINT ["/sbin/tini", "/entrypoint.sh", "-o", "LogLevel=DEBUG2"]

View File

@@ -1,42 +0,0 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj
import net.schmizz.sshj.Config
import net.schmizz.sshj.DefaultConfig
import net.schmizz.sshj.SSHClient
import net.schmizz.sshj.transport.verification.PromiscuousVerifier
import spock.lang.Specification
class IntegrationBaseSpec extends Specification {
protected static final int DOCKER_PORT = 2222
protected static final String USERNAME = "sshj"
protected static final String KEYFILE = "src/itest/resources/keyfiles/id_rsa"
protected final static String SERVER_IP = System.getProperty("serverIP", "127.0.0.1")
protected static SSHClient getConnectedClient(Config config) {
SSHClient sshClient = new SSHClient(config)
sshClient.addHostKeyVerifier(new PromiscuousVerifier())
sshClient.connect(SERVER_IP, DOCKER_PORT)
return sshClient
}
protected static SSHClient getConnectedClient() throws IOException {
return getConnectedClient(new DefaultConfig())
}
}

View File

@@ -20,9 +20,15 @@ import net.schmizz.sshj.DefaultConfig
import net.schmizz.sshj.SSHClient import net.schmizz.sshj.SSHClient
import net.schmizz.sshj.transport.TransportException import net.schmizz.sshj.transport.TransportException
import net.schmizz.sshj.userauth.UserAuthException import net.schmizz.sshj.userauth.UserAuthException
import org.junit.ClassRule
import spock.lang.Shared
import spock.lang.Specification
import spock.lang.Unroll import spock.lang.Unroll
class IntegrationSpec extends IntegrationBaseSpec { class IntegrationSpec extends Specification {
@Shared
@ClassRule
SshdContainer sshd
@Unroll @Unroll
def "should accept correct key for #signatureName"() { def "should accept correct key for #signatureName"() {
@@ -33,7 +39,7 @@ class IntegrationSpec extends IntegrationBaseSpec {
sshClient.addHostKeyVerifier(fingerprint) // test-containers/ssh_host_ecdsa_key's fingerprint sshClient.addHostKeyVerifier(fingerprint) // test-containers/ssh_host_ecdsa_key's fingerprint
when: when:
sshClient.connect(SERVER_IP, DOCKER_PORT) sshClient.connect(sshd.containerIpAddress, sshd.firstMappedPort)
then: then:
sshClient.isConnected() sshClient.isConnected()
@@ -50,7 +56,7 @@ class IntegrationSpec extends IntegrationBaseSpec {
sshClient.addHostKeyVerifier("d4:6a:a9:52:05:ab:b5:48:dd:73:60:18:0c:3a:f0:a3") sshClient.addHostKeyVerifier("d4:6a:a9:52:05:ab:b5:48:dd:73:60:18:0c:3a:f0:a3")
when: when:
sshClient.connect(SERVER_IP, DOCKER_PORT) sshClient.connect(sshd.containerIpAddress, sshd.firstMappedPort)
then: then:
thrown(TransportException.class) thrown(TransportException.class)
@@ -59,11 +65,11 @@ class IntegrationSpec extends IntegrationBaseSpec {
@Unroll @Unroll
def "should authenticate with key #key"() { def "should authenticate with key #key"() {
given: given:
SSHClient client = getConnectedClient() SSHClient client = sshd.getConnectedClient()
when: when:
def keyProvider = passphrase != null ? client.loadKeys("src/itest/resources/keyfiles/$key", passphrase) : client.loadKeys("src/itest/resources/keyfiles/$key") def keyProvider = passphrase != null ? client.loadKeys("src/itest/resources/keyfiles/$key", passphrase) : client.loadKeys("src/itest/resources/keyfiles/$key")
client.authPublickey(USERNAME, keyProvider) client.authPublickey(IntegrationTestUtil.USERNAME, keyProvider)
then: then:
client.isAuthenticated() client.isAuthenticated()
@@ -83,7 +89,7 @@ class IntegrationSpec extends IntegrationBaseSpec {
def "should not authenticate with wrong key"() { def "should not authenticate with wrong key"() {
given: given:
SSHClient client = getConnectedClient() SSHClient client = sshd.getConnectedClient()
when: when:
client.authPublickey("sshj", "src/itest/resources/keyfiles/id_unknown_key") client.authPublickey("sshj", "src/itest/resources/keyfiles/id_unknown_key")

View File

@@ -0,0 +1,21 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj
class IntegrationTestUtil {
static final String USERNAME = "sshj"
static final String KEYFILE = "src/itest/resources/keyfiles/id_rsa"
}

View File

@@ -0,0 +1,77 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj;
import org.testcontainers.containers.wait.strategy.WaitStrategy;
import org.testcontainers.containers.wait.strategy.WaitStrategyTarget;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Arrays;
/**
* A wait strategy designed for {@link SshdContainer} to wait until the SSH server is ready, to avoid races when a test
* tries to connect to a server before the server has started.
*/
public class SshServerWaitStrategy implements WaitStrategy {
private Duration startupTimeout = Duration.ofMinutes(1);
@Override
public void waitUntilReady(WaitStrategyTarget waitStrategyTarget) {
long expectedEnd = System.nanoTime() + startupTimeout.toNanos();
while (true) {
long attemptStart = System.nanoTime();
IOException error = null;
byte[] buffer = new byte[7];
try (Socket socket = new Socket()) {
socket.setSoTimeout(500);
socket.connect(new InetSocketAddress(
waitStrategyTarget.getHost(), waitStrategyTarget.getFirstMappedPort()));
// Haven't seen any SSH server that sends the version in two or more packets.
//noinspection ResultOfMethodCallIgnored
socket.getInputStream().read(buffer);
if (!Arrays.equals(buffer, "SSH-2.0".getBytes(StandardCharsets.UTF_8))) {
error = new IOException("The version message doesn't look like an SSH server version");
}
} catch (IOException err) {
error = err;
}
if (error == null) {
break;
} else if (System.nanoTime() >= expectedEnd) {
throw new RuntimeException(error);
}
try {
//noinspection BusyWait
Thread.sleep(Math.max(0L, 500L - (System.nanoTime() - attemptStart) / 1_000_000));
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}
@Override
public WaitStrategy withStartupTimeout(Duration startupTimeout) {
this.startupTimeout = startupTimeout;
return this;
}
}

View File

@@ -0,0 +1,84 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj;
import net.schmizz.sshj.Config;
import net.schmizz.sshj.DefaultConfig;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.transport.verification.PromiscuousVerifier;
import org.jetbrains.annotations.NotNull;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.images.builder.ImageFromDockerfile;
import org.testcontainers.images.builder.dockerfile.DockerfileBuilder;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.concurrent.Future;
/**
* A JUnit4 rule for launching a generic SSH server container.
*/
public class SshdContainer extends GenericContainer<SshdContainer> {
@SuppressWarnings("unused") // Used dynamically by Spock
public SshdContainer() {
this(new ImageFromDockerfile()
.withDockerfileFromBuilder(SshdContainer::defaultDockerfileBuilder)
.withFileFromPath(".", Paths.get("src/itest/docker-image")));
}
public SshdContainer(@NotNull Future<String> future) {
super(future);
withExposedPorts(22);
setWaitStrategy(new SshServerWaitStrategy());
}
public static void defaultDockerfileBuilder(@NotNull DockerfileBuilder builder) {
builder.from("sickp/alpine-sshd:7.5-r2");
builder.add("authorized_keys", "/home/sshj/.ssh/authorized_keys");
builder.add("test-container/ssh_host_ecdsa_key", "/etc/ssh/ssh_host_ecdsa_key");
builder.add("test-container/ssh_host_ecdsa_key.pub", "/etc/ssh/ssh_host_ecdsa_key.pub");
builder.add("test-container/ssh_host_ed25519_key", "/etc/ssh/ssh_host_ed25519_key");
builder.add("test-container/ssh_host_ed25519_key.pub", "/etc/ssh/ssh_host_ed25519_key.pub");
builder.add("test-container/sshd_config", "/etc/ssh/sshd_config");
builder.copy("test-container/trusted_ca_keys", "/etc/ssh/trusted_ca_keys");
builder.copy("test-container/host_keys/*", "/etc/ssh/");
builder.run("apk add --no-cache tini"
+ " && echo \"root:smile\" | chpasswd"
+ " && adduser -D -s /bin/ash sshj"
+ " && passwd -u sshj"
+ " && echo \"sshj:ultrapassword\" | chpasswd"
+ " && chmod 600 /home/sshj/.ssh/authorized_keys"
+ " && chmod 600 /etc/ssh/ssh_host_*_key"
+ " && chmod 644 /etc/ssh/*.pub"
+ " && chown -R sshj:sshj /home/sshj");
builder.entryPoint("/sbin/tini", "/entrypoint.sh", "-o", "LogLevel=DEBUG2");
}
public SSHClient getConnectedClient(Config config) throws IOException {
SSHClient sshClient = new SSHClient(config);
sshClient.addHostKeyVerifier(new PromiscuousVerifier());
sshClient.connect("127.0.0.1", getFirstMappedPort());
return sshClient;
}
public SSHClient getConnectedClient() throws IOException {
return getConnectedClient(new DefaultConfig());
}
}

View File

@@ -15,21 +15,28 @@
*/ */
package com.hierynomus.sshj.sftp package com.hierynomus.sshj.sftp
import com.hierynomus.sshj.IntegrationBaseSpec import com.hierynomus.sshj.IntegrationTestUtil
import com.hierynomus.sshj.SshdContainer
import net.schmizz.sshj.SSHClient import net.schmizz.sshj.SSHClient
import net.schmizz.sshj.sftp.OpenMode import net.schmizz.sshj.sftp.OpenMode
import net.schmizz.sshj.sftp.RemoteFile import net.schmizz.sshj.sftp.RemoteFile
import net.schmizz.sshj.sftp.SFTPClient import net.schmizz.sshj.sftp.SFTPClient
import org.junit.ClassRule
import spock.lang.Shared
import spock.lang.Specification
import java.nio.charset.StandardCharsets import java.nio.charset.StandardCharsets
import static org.codehaus.groovy.runtime.IOGroovyMethods.withCloseable import static org.codehaus.groovy.runtime.IOGroovyMethods.withCloseable
class FileWriteSpec extends IntegrationBaseSpec { class FileWriteSpec extends Specification {
@Shared
@ClassRule
SshdContainer sshd
def "should append to file (GH issue #390)"() { def "should append to file (GH issue #390)"() {
given: given:
SSHClient client = getConnectedClient() SSHClient client = sshd.getConnectedClient()
client.authPublickey("sshj", "src/test/resources/id_rsa") client.authPublickey("sshj", "src/test/resources/id_rsa")
SFTPClient sftp = client.newSFTPClient() SFTPClient sftp = client.newSFTPClient()
def file = "/home/sshj/test.txt" def file = "/home/sshj/test.txt"

View File

@@ -15,10 +15,14 @@
*/ */
package com.hierynomus.sshj.signature package com.hierynomus.sshj.signature
import com.hierynomus.sshj.IntegrationBaseSpec import com.hierynomus.sshj.SshdContainer
import net.schmizz.sshj.DefaultConfig import net.schmizz.sshj.DefaultConfig
import net.schmizz.sshj.SSHClient import net.schmizz.sshj.SSHClient
import net.schmizz.sshj.transport.verification.OpenSSHKnownHosts import net.schmizz.sshj.transport.verification.OpenSSHKnownHosts
import net.schmizz.sshj.transport.verification.PromiscuousVerifier
import org.junit.ClassRule
import spock.lang.Shared
import spock.lang.Specification
import spock.lang.Unroll import spock.lang.Unroll
import java.nio.file.Files import java.nio.file.Files
@@ -29,15 +33,20 @@ import java.util.stream.Collectors
* *
* Also, take a look at the unit test {@link net.schmizz.sshj.transport.verification.KeyWithCertificateUnitSpec}. * Also, take a look at the unit test {@link net.schmizz.sshj.transport.verification.KeyWithCertificateUnitSpec}.
*/ */
class KeyWithCertificateSpec extends IntegrationBaseSpec { class KeyWithCertificateSpec extends Specification {
@Shared
@ClassRule
SshdContainer sshd
@Unroll @Unroll
def "authorising with a signed public key #keyName"() { def "authorising with a signed public key #keyName"() {
given: given:
def client = getConnectedClient() SSHClient client = new SSHClient(new DefaultConfig())
client.addHostKeyVerifier(new PromiscuousVerifier())
client.connect("127.0.0.1", sshd.firstMappedPort)
when: when:
client.authPublickey(USERNAME, "src/itest/resources/keyfiles/certificates/$keyName") client.authPublickey("sshj", "src/itest/resources/keyfiles/certificates/$keyName")
then: then:
client.authenticated client.authenticated
@@ -82,9 +91,10 @@ class KeyWithCertificateSpec extends IntegrationBaseSpec {
and: and:
File caPubKey = new File("src/itest/resources/keyfiles/certificates/CA_rsa.pem.pub") File caPubKey = new File("src/itest/resources/keyfiles/certificates/CA_rsa.pem.pub")
def address = "127.0.0.1"
String knownHostsFileContents = "" + String knownHostsFileContents = "" +
"@cert-authority $SERVER_IP ${caPubKey.text}" + "@cert-authority ${ address} ${caPubKey.text}" +
"\n@cert-authority [$SERVER_IP]:$DOCKER_PORT ${caPubKey.text}" "\n@cert-authority [${address}]:${sshd.firstMappedPort} ${caPubKey.text}"
knownHosts.write(knownHostsFileContents) knownHosts.write(knownHostsFileContents)
and: and:
@@ -94,7 +104,7 @@ class KeyWithCertificateSpec extends IntegrationBaseSpec {
.collect(Collectors.toList()) .collect(Collectors.toList())
SSHClient sshClient = new SSHClient(config) SSHClient sshClient = new SSHClient(config)
sshClient.addHostKeyVerifier(new OpenSSHKnownHosts(knownHosts)) sshClient.addHostKeyVerifier(new OpenSSHKnownHosts(knownHosts))
sshClient.connect(SERVER_IP, DOCKER_PORT) sshClient.connect(address, sshd.firstMappedPort)
when: when:
sshClient.authPassword("sshj", "ultrapassword") sshClient.authPassword("sshj", "ultrapassword")

View File

@@ -15,18 +15,25 @@
*/ */
package com.hierynomus.sshj.signature package com.hierynomus.sshj.signature
import com.hierynomus.sshj.IntegrationBaseSpec import com.hierynomus.sshj.IntegrationTestUtil
import net.schmizz.sshj.DefaultConfig import com.hierynomus.sshj.SshdContainer
import org.junit.ClassRule
import spock.lang.Shared
import spock.lang.Specification
import spock.lang.Unroll import spock.lang.Unroll
class RsaSignatureClientKeySpec extends IntegrationBaseSpec { class RsaSignatureClientKeySpec extends Specification {
@Shared
@ClassRule
SshdContainer sshd
@Unroll @Unroll
def "should correctly connect using publickey auth with RSA key with signature"() { def "should correctly connect using publickey auth with RSA key with signature"() {
given: given:
def client = getConnectedClient(new DefaultConfig()) def client = sshd.getConnectedClient()
when: when:
client.authPublickey(USERNAME, "src/itest/resources/keyfiles/id_rsa2") client.authPublickey(IntegrationTestUtil.USERNAME, "src/itest/resources/keyfiles/id_rsa2")
then: then:
client.authenticated client.authenticated

View File

@@ -15,22 +15,29 @@
*/ */
package com.hierynomus.sshj.signature package com.hierynomus.sshj.signature
import com.hierynomus.sshj.IntegrationBaseSpec import com.hierynomus.sshj.IntegrationTestUtil
import com.hierynomus.sshj.SshdContainer
import com.hierynomus.sshj.key.KeyAlgorithms import com.hierynomus.sshj.key.KeyAlgorithms
import net.schmizz.sshj.DefaultConfig import net.schmizz.sshj.DefaultConfig
import org.junit.ClassRule
import spock.lang.Shared
import spock.lang.Specification
import spock.lang.Unroll import spock.lang.Unroll
class SignatureSpec extends IntegrationBaseSpec { class SignatureSpec extends Specification {
@Shared
@ClassRule
SshdContainer sshd
@Unroll @Unroll
def "should correctly connect with #sig Signature"() { def "should correctly connect with #sig Signature"() {
given: given:
def cfg = new DefaultConfig() def cfg = new DefaultConfig()
cfg.setKeyAlgorithms(Collections.singletonList(sigFactory)) cfg.setKeyAlgorithms(Collections.singletonList(sigFactory))
def client = getConnectedClient(cfg) def client = sshd.getConnectedClient(cfg)
when: when:
client.authPublickey(USERNAME, KEYFILE) client.authPublickey(IntegrationTestUtil.USERNAME, IntegrationTestUtil.KEYFILE)
then: then:
client.authenticated client.authenticated

View File

@@ -15,21 +15,28 @@
*/ */
package com.hierynomus.sshj.transport.cipher package com.hierynomus.sshj.transport.cipher
import com.hierynomus.sshj.IntegrationBaseSpec import com.hierynomus.sshj.IntegrationTestUtil
import com.hierynomus.sshj.SshdContainer
import net.schmizz.sshj.DefaultConfig import net.schmizz.sshj.DefaultConfig
import org.junit.ClassRule
import spock.lang.Shared
import spock.lang.Specification
import spock.lang.Unroll import spock.lang.Unroll
class CipherSpec extends IntegrationBaseSpec { class CipherSpec extends Specification {
@Shared
@ClassRule
SshdContainer sshd
@Unroll @Unroll
def "should correctly connect with #cipher Cipher"() { def "should correctly connect with #cipher Cipher"() {
given: given:
def cfg = new DefaultConfig() def cfg = new DefaultConfig()
cfg.setCipherFactories(cipherFactory) cfg.setCipherFactories(cipherFactory)
def client = getConnectedClient(cfg) def client = sshd.getConnectedClient(cfg)
when: when:
client.authPublickey(USERNAME, KEYFILE) client.authPublickey(IntegrationTestUtil.USERNAME, IntegrationTestUtil.KEYFILE)
then: then:
client.authenticated client.authenticated

View File

@@ -15,29 +15,32 @@
*/ */
package com.hierynomus.sshj.transport.kex package com.hierynomus.sshj.transport.kex
import com.hierynomus.sshj.IntegrationBaseSpec import com.hierynomus.sshj.IntegrationTestUtil
import com.hierynomus.sshj.transport.mac.Macs import com.hierynomus.sshj.SshdContainer
import net.schmizz.sshj.DefaultConfig import net.schmizz.sshj.DefaultConfig
import net.schmizz.sshj.transport.kex.Curve25519DH
import net.schmizz.sshj.transport.kex.Curve25519SHA256 import net.schmizz.sshj.transport.kex.Curve25519SHA256
import net.schmizz.sshj.transport.kex.DH
import net.schmizz.sshj.transport.kex.DHGexSHA1 import net.schmizz.sshj.transport.kex.DHGexSHA1
import net.schmizz.sshj.transport.kex.DHGexSHA256 import net.schmizz.sshj.transport.kex.DHGexSHA256
import net.schmizz.sshj.transport.kex.ECDH
import net.schmizz.sshj.transport.kex.ECDHNistP import net.schmizz.sshj.transport.kex.ECDHNistP
import org.junit.ClassRule
import spock.lang.Shared
import spock.lang.Specification
import spock.lang.Unroll import spock.lang.Unroll
class KexSpec extends IntegrationBaseSpec { class KexSpec extends Specification {
@Shared
@ClassRule
SshdContainer sshd
@Unroll @Unroll
def "should correctly connect with #kex Key Exchange"() { def "should correctly connect with #kex Key Exchange"() {
given: given:
def cfg = new DefaultConfig() def cfg = new DefaultConfig()
cfg.setKeyExchangeFactories(kexFactory) cfg.setKeyExchangeFactories(kexFactory)
def client = getConnectedClient(cfg) def client = sshd.getConnectedClient(cfg)
when: when:
client.authPublickey(USERNAME, KEYFILE) client.authPublickey(IntegrationTestUtil.USERNAME, IntegrationTestUtil.KEYFILE)
then: then:
client.authenticated client.authenticated

View File

@@ -15,21 +15,28 @@
*/ */
package com.hierynomus.sshj.transport.mac package com.hierynomus.sshj.transport.mac
import com.hierynomus.sshj.IntegrationBaseSpec import com.hierynomus.sshj.IntegrationTestUtil
import com.hierynomus.sshj.SshdContainer
import net.schmizz.sshj.DefaultConfig import net.schmizz.sshj.DefaultConfig
import org.junit.ClassRule
import spock.lang.Shared
import spock.lang.Specification
import spock.lang.Unroll import spock.lang.Unroll
class MacSpec extends IntegrationBaseSpec { class MacSpec extends Specification {
@Shared
@ClassRule
SshdContainer sshd
@Unroll @Unroll
def "should correctly connect with #mac MAC"() { def "should correctly connect with #mac MAC"() {
given: given:
def cfg = new DefaultConfig() def cfg = new DefaultConfig()
cfg.setMACFactories(macFactory) cfg.setMACFactories(macFactory)
def client = getConnectedClient(cfg) def client = sshd.getConnectedClient(cfg)
when: when:
client.authPublickey(USERNAME, KEYFILE) client.authPublickey(IntegrationTestUtil.USERNAME, IntegrationTestUtil.KEYFILE)
then: then:
client.authenticated client.authenticated
@@ -47,10 +54,10 @@ class MacSpec extends IntegrationBaseSpec {
given: given:
def cfg = new DefaultConfig() def cfg = new DefaultConfig()
cfg.setMACFactories(macFactory) cfg.setMACFactories(macFactory)
def client = getConnectedClient(cfg) def client = sshd.getConnectedClient(cfg)
when: when:
client.authPublickey(USERNAME, KEYFILE) client.authPublickey(IntegrationTestUtil.USERNAME, IntegrationTestUtil.KEYFILE)
then: then:
client.authenticated client.authenticated