From d5805a6c6455032855ab0a8d2d8b325feab034ad Mon Sep 17 00:00:00 2001 From: Vladimir Lagunov Date: Wed, 10 Nov 2021 20:30:35 +0700 Subject: [PATCH] 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. --- build.gradle | 43 +--------- src/itest/docker-image/Dockerfile | 24 ------ .../sshj/IntegrationBaseSpec.groovy | 42 ---------- .../hierynomus/sshj/IntegrationSpec.groovy | 18 ++-- .../sshj/IntegrationTestUtil.groovy | 21 +++++ .../sshj/SshServerWaitStrategy.java | 77 +++++++++++++++++ .../com/hierynomus/sshj/SshdContainer.java | 84 +++++++++++++++++++ .../hierynomus/sshj/sftp/FileWriteSpec.groovy | 13 ++- .../signature/KeyWithCertificateSpec.groovy | 24 ++++-- .../RsaSignatureClientKeySpec.groovy | 17 ++-- .../sshj/signature/SignatureSpec.groovy | 15 +++- .../sshj/transport/cipher/CipherSpec.groovy | 15 +++- .../sshj/transport/kex/KexSpec.groovy | 19 +++-- .../sshj/transport/mac/MacSpec.groovy | 19 +++-- 14 files changed, 280 insertions(+), 151 deletions(-) delete mode 100644 src/itest/docker-image/Dockerfile delete mode 100644 src/itest/groovy/com/hierynomus/sshj/IntegrationBaseSpec.groovy create mode 100644 src/itest/groovy/com/hierynomus/sshj/IntegrationTestUtil.groovy create mode 100644 src/itest/groovy/com/hierynomus/sshj/SshServerWaitStrategy.java create mode 100644 src/itest/groovy/com/hierynomus/sshj/SshdContainer.java diff --git a/build.gradle b/build.gradle index 5e0596c0e..777cb3d35 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,3 @@ -import java.text.SimpleDateFormat -import com.bmuschko.gradle.docker.tasks.container.* -import com.bmuschko.gradle.docker.tasks.image.* - plugins { id "java" id "groovy" @@ -60,7 +56,7 @@ dependencies { testRuntimeOnly "ch.qos.logback:logback-classic:1.2.6" testImplementation 'org.glassfish.grizzly:grizzly-http-server:2.4.4' testImplementation 'org.apache.httpcomponents:httpclient:4.5.9' - + testImplementation 'org.testcontainers:testcontainers:1.16.2' } 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) { buildFile = project.buildFile 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.finalizedBy(project.tasks.forkedUploadRelease) project.tasks.jacocoTestReport.dependsOn(project.tasks.test) diff --git a/src/itest/docker-image/Dockerfile b/src/itest/docker-image/Dockerfile deleted file mode 100644 index 56a6414b7..000000000 --- a/src/itest/docker-image/Dockerfile +++ /dev/null @@ -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"] \ No newline at end of file diff --git a/src/itest/groovy/com/hierynomus/sshj/IntegrationBaseSpec.groovy b/src/itest/groovy/com/hierynomus/sshj/IntegrationBaseSpec.groovy deleted file mode 100644 index e62b49e6b..000000000 --- a/src/itest/groovy/com/hierynomus/sshj/IntegrationBaseSpec.groovy +++ /dev/null @@ -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()) - } - -} diff --git a/src/itest/groovy/com/hierynomus/sshj/IntegrationSpec.groovy b/src/itest/groovy/com/hierynomus/sshj/IntegrationSpec.groovy index 060384f08..f4b10eb64 100644 --- a/src/itest/groovy/com/hierynomus/sshj/IntegrationSpec.groovy +++ b/src/itest/groovy/com/hierynomus/sshj/IntegrationSpec.groovy @@ -20,9 +20,15 @@ import net.schmizz.sshj.DefaultConfig import net.schmizz.sshj.SSHClient import net.schmizz.sshj.transport.TransportException import net.schmizz.sshj.userauth.UserAuthException +import org.junit.ClassRule +import spock.lang.Shared +import spock.lang.Specification import spock.lang.Unroll -class IntegrationSpec extends IntegrationBaseSpec { +class IntegrationSpec extends Specification { + @Shared + @ClassRule + SshdContainer sshd @Unroll 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 when: - sshClient.connect(SERVER_IP, DOCKER_PORT) + sshClient.connect(sshd.containerIpAddress, sshd.firstMappedPort) then: 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") when: - sshClient.connect(SERVER_IP, DOCKER_PORT) + sshClient.connect(sshd.containerIpAddress, sshd.firstMappedPort) then: thrown(TransportException.class) @@ -59,11 +65,11 @@ class IntegrationSpec extends IntegrationBaseSpec { @Unroll def "should authenticate with key #key"() { given: - SSHClient client = getConnectedClient() + SSHClient client = sshd.getConnectedClient() when: 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: client.isAuthenticated() @@ -83,7 +89,7 @@ class IntegrationSpec extends IntegrationBaseSpec { def "should not authenticate with wrong key"() { given: - SSHClient client = getConnectedClient() + SSHClient client = sshd.getConnectedClient() when: client.authPublickey("sshj", "src/itest/resources/keyfiles/id_unknown_key") diff --git a/src/itest/groovy/com/hierynomus/sshj/IntegrationTestUtil.groovy b/src/itest/groovy/com/hierynomus/sshj/IntegrationTestUtil.groovy new file mode 100644 index 000000000..75271e6e7 --- /dev/null +++ b/src/itest/groovy/com/hierynomus/sshj/IntegrationTestUtil.groovy @@ -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" +} diff --git a/src/itest/groovy/com/hierynomus/sshj/SshServerWaitStrategy.java b/src/itest/groovy/com/hierynomus/sshj/SshServerWaitStrategy.java new file mode 100644 index 000000000..3dec03363 --- /dev/null +++ b/src/itest/groovy/com/hierynomus/sshj/SshServerWaitStrategy.java @@ -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; + } +} diff --git a/src/itest/groovy/com/hierynomus/sshj/SshdContainer.java b/src/itest/groovy/com/hierynomus/sshj/SshdContainer.java new file mode 100644 index 000000000..98f6927d2 --- /dev/null +++ b/src/itest/groovy/com/hierynomus/sshj/SshdContainer.java @@ -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 { + @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 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()); + } +} diff --git a/src/itest/groovy/com/hierynomus/sshj/sftp/FileWriteSpec.groovy b/src/itest/groovy/com/hierynomus/sshj/sftp/FileWriteSpec.groovy index d61187df4..95179a38a 100644 --- a/src/itest/groovy/com/hierynomus/sshj/sftp/FileWriteSpec.groovy +++ b/src/itest/groovy/com/hierynomus/sshj/sftp/FileWriteSpec.groovy @@ -15,21 +15,28 @@ */ 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.sftp.OpenMode import net.schmizz.sshj.sftp.RemoteFile import net.schmizz.sshj.sftp.SFTPClient +import org.junit.ClassRule +import spock.lang.Shared +import spock.lang.Specification import java.nio.charset.StandardCharsets 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)"() { given: - SSHClient client = getConnectedClient() + SSHClient client = sshd.getConnectedClient() client.authPublickey("sshj", "src/test/resources/id_rsa") SFTPClient sftp = client.newSFTPClient() def file = "/home/sshj/test.txt" diff --git a/src/itest/groovy/com/hierynomus/sshj/signature/KeyWithCertificateSpec.groovy b/src/itest/groovy/com/hierynomus/sshj/signature/KeyWithCertificateSpec.groovy index 78fbb8a0e..ea7fa50ab 100644 --- a/src/itest/groovy/com/hierynomus/sshj/signature/KeyWithCertificateSpec.groovy +++ b/src/itest/groovy/com/hierynomus/sshj/signature/KeyWithCertificateSpec.groovy @@ -15,10 +15,14 @@ */ package com.hierynomus.sshj.signature -import com.hierynomus.sshj.IntegrationBaseSpec +import com.hierynomus.sshj.SshdContainer import net.schmizz.sshj.DefaultConfig import net.schmizz.sshj.SSHClient 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 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}. */ -class KeyWithCertificateSpec extends IntegrationBaseSpec { +class KeyWithCertificateSpec extends Specification { + @Shared + @ClassRule + SshdContainer sshd @Unroll def "authorising with a signed public key #keyName"() { given: - def client = getConnectedClient() + SSHClient client = new SSHClient(new DefaultConfig()) + client.addHostKeyVerifier(new PromiscuousVerifier()) + client.connect("127.0.0.1", sshd.firstMappedPort) when: - client.authPublickey(USERNAME, "src/itest/resources/keyfiles/certificates/$keyName") + client.authPublickey("sshj", "src/itest/resources/keyfiles/certificates/$keyName") then: client.authenticated @@ -82,9 +91,10 @@ class KeyWithCertificateSpec extends IntegrationBaseSpec { and: File caPubKey = new File("src/itest/resources/keyfiles/certificates/CA_rsa.pem.pub") + def address = "127.0.0.1" String knownHostsFileContents = "" + - "@cert-authority $SERVER_IP ${caPubKey.text}" + - "\n@cert-authority [$SERVER_IP]:$DOCKER_PORT ${caPubKey.text}" + "@cert-authority ${ address} ${caPubKey.text}" + + "\n@cert-authority [${address}]:${sshd.firstMappedPort} ${caPubKey.text}" knownHosts.write(knownHostsFileContents) and: @@ -94,7 +104,7 @@ class KeyWithCertificateSpec extends IntegrationBaseSpec { .collect(Collectors.toList()) SSHClient sshClient = new SSHClient(config) sshClient.addHostKeyVerifier(new OpenSSHKnownHosts(knownHosts)) - sshClient.connect(SERVER_IP, DOCKER_PORT) + sshClient.connect(address, sshd.firstMappedPort) when: sshClient.authPassword("sshj", "ultrapassword") diff --git a/src/itest/groovy/com/hierynomus/sshj/signature/RsaSignatureClientKeySpec.groovy b/src/itest/groovy/com/hierynomus/sshj/signature/RsaSignatureClientKeySpec.groovy index 7cf215944..df0487634 100644 --- a/src/itest/groovy/com/hierynomus/sshj/signature/RsaSignatureClientKeySpec.groovy +++ b/src/itest/groovy/com/hierynomus/sshj/signature/RsaSignatureClientKeySpec.groovy @@ -15,18 +15,25 @@ */ package com.hierynomus.sshj.signature -import com.hierynomus.sshj.IntegrationBaseSpec -import net.schmizz.sshj.DefaultConfig +import com.hierynomus.sshj.IntegrationTestUtil +import com.hierynomus.sshj.SshdContainer +import org.junit.ClassRule +import spock.lang.Shared +import spock.lang.Specification import spock.lang.Unroll -class RsaSignatureClientKeySpec extends IntegrationBaseSpec { +class RsaSignatureClientKeySpec extends Specification { + @Shared + @ClassRule + SshdContainer sshd + @Unroll def "should correctly connect using publickey auth with RSA key with signature"() { given: - def client = getConnectedClient(new DefaultConfig()) + def client = sshd.getConnectedClient() when: - client.authPublickey(USERNAME, "src/itest/resources/keyfiles/id_rsa2") + client.authPublickey(IntegrationTestUtil.USERNAME, "src/itest/resources/keyfiles/id_rsa2") then: client.authenticated diff --git a/src/itest/groovy/com/hierynomus/sshj/signature/SignatureSpec.groovy b/src/itest/groovy/com/hierynomus/sshj/signature/SignatureSpec.groovy index 27445eaeb..d431738a2 100644 --- a/src/itest/groovy/com/hierynomus/sshj/signature/SignatureSpec.groovy +++ b/src/itest/groovy/com/hierynomus/sshj/signature/SignatureSpec.groovy @@ -15,22 +15,29 @@ */ 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 net.schmizz.sshj.DefaultConfig +import org.junit.ClassRule +import spock.lang.Shared +import spock.lang.Specification import spock.lang.Unroll -class SignatureSpec extends IntegrationBaseSpec { +class SignatureSpec extends Specification { + @Shared + @ClassRule + SshdContainer sshd @Unroll def "should correctly connect with #sig Signature"() { given: def cfg = new DefaultConfig() cfg.setKeyAlgorithms(Collections.singletonList(sigFactory)) - def client = getConnectedClient(cfg) + def client = sshd.getConnectedClient(cfg) when: - client.authPublickey(USERNAME, KEYFILE) + client.authPublickey(IntegrationTestUtil.USERNAME, IntegrationTestUtil.KEYFILE) then: client.authenticated diff --git a/src/itest/groovy/com/hierynomus/sshj/transport/cipher/CipherSpec.groovy b/src/itest/groovy/com/hierynomus/sshj/transport/cipher/CipherSpec.groovy index 5f3c8c755..bc6687d8c 100644 --- a/src/itest/groovy/com/hierynomus/sshj/transport/cipher/CipherSpec.groovy +++ b/src/itest/groovy/com/hierynomus/sshj/transport/cipher/CipherSpec.groovy @@ -15,21 +15,28 @@ */ 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 org.junit.ClassRule +import spock.lang.Shared +import spock.lang.Specification import spock.lang.Unroll -class CipherSpec extends IntegrationBaseSpec { +class CipherSpec extends Specification { + @Shared + @ClassRule + SshdContainer sshd @Unroll def "should correctly connect with #cipher Cipher"() { given: def cfg = new DefaultConfig() cfg.setCipherFactories(cipherFactory) - def client = getConnectedClient(cfg) + def client = sshd.getConnectedClient(cfg) when: - client.authPublickey(USERNAME, KEYFILE) + client.authPublickey(IntegrationTestUtil.USERNAME, IntegrationTestUtil.KEYFILE) then: client.authenticated diff --git a/src/itest/groovy/com/hierynomus/sshj/transport/kex/KexSpec.groovy b/src/itest/groovy/com/hierynomus/sshj/transport/kex/KexSpec.groovy index c0bc72adb..944be9f3a 100644 --- a/src/itest/groovy/com/hierynomus/sshj/transport/kex/KexSpec.groovy +++ b/src/itest/groovy/com/hierynomus/sshj/transport/kex/KexSpec.groovy @@ -15,29 +15,32 @@ */ package com.hierynomus.sshj.transport.kex -import com.hierynomus.sshj.IntegrationBaseSpec -import com.hierynomus.sshj.transport.mac.Macs +import com.hierynomus.sshj.IntegrationTestUtil +import com.hierynomus.sshj.SshdContainer 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.DH import net.schmizz.sshj.transport.kex.DHGexSHA1 import net.schmizz.sshj.transport.kex.DHGexSHA256 -import net.schmizz.sshj.transport.kex.ECDH import net.schmizz.sshj.transport.kex.ECDHNistP +import org.junit.ClassRule +import spock.lang.Shared +import spock.lang.Specification import spock.lang.Unroll -class KexSpec extends IntegrationBaseSpec { +class KexSpec extends Specification { + @Shared + @ClassRule + SshdContainer sshd @Unroll def "should correctly connect with #kex Key Exchange"() { given: def cfg = new DefaultConfig() cfg.setKeyExchangeFactories(kexFactory) - def client = getConnectedClient(cfg) + def client = sshd.getConnectedClient(cfg) when: - client.authPublickey(USERNAME, KEYFILE) + client.authPublickey(IntegrationTestUtil.USERNAME, IntegrationTestUtil.KEYFILE) then: client.authenticated diff --git a/src/itest/groovy/com/hierynomus/sshj/transport/mac/MacSpec.groovy b/src/itest/groovy/com/hierynomus/sshj/transport/mac/MacSpec.groovy index 460038838..fe616cddb 100644 --- a/src/itest/groovy/com/hierynomus/sshj/transport/mac/MacSpec.groovy +++ b/src/itest/groovy/com/hierynomus/sshj/transport/mac/MacSpec.groovy @@ -15,21 +15,28 @@ */ 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 org.junit.ClassRule +import spock.lang.Shared +import spock.lang.Specification import spock.lang.Unroll -class MacSpec extends IntegrationBaseSpec { +class MacSpec extends Specification { + @Shared + @ClassRule + SshdContainer sshd @Unroll def "should correctly connect with #mac MAC"() { given: def cfg = new DefaultConfig() cfg.setMACFactories(macFactory) - def client = getConnectedClient(cfg) + def client = sshd.getConnectedClient(cfg) when: - client.authPublickey(USERNAME, KEYFILE) + client.authPublickey(IntegrationTestUtil.USERNAME, IntegrationTestUtil.KEYFILE) then: client.authenticated @@ -47,10 +54,10 @@ class MacSpec extends IntegrationBaseSpec { given: def cfg = new DefaultConfig() cfg.setMACFactories(macFactory) - def client = getConnectedClient(cfg) + def client = sshd.getConnectedClient(cfg) when: - client.authPublickey(USERNAME, KEYFILE) + client.authPublickey(IntegrationTestUtil.USERNAME, IntegrationTestUtil.KEYFILE) then: client.authenticated