diff --git a/build.gradle b/build.gradle index 86dcb72c..81b1f30b 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,6 @@ import java.text.SimpleDateFormat +import com.bmuschko.gradle.docker.tasks.container.* +import com.bmuschko.gradle.docker.tasks.image.* plugins { id "java" @@ -6,6 +8,7 @@ plugins { id "jacoco" id "osgi" id "maven-publish" + id "com.bmuschko.docker-remote-api" version "3.2.1" id 'pl.allegro.tech.build.axion-release' version '1.8.1' id "com.github.hierynomus.license" version "0.12.1" id "com.jfrog.bintray" version "1.7" @@ -125,6 +128,27 @@ sourcesJar { } } +configurations { + integrationTestCompile.extendsFrom testCompile + integrationTestRuntime.extendsFrom testRuntime +} + +sourceSets { + integrationTest { + groovy { + compileClasspath += sourceSets.main.output + sourceSets.test.output + runtimeClasspath += sourceSets.main.output + sourceSets.test.output + srcDir file('src/itest/groovy') + } + resources.srcDir file('src/itest/resources') + } +} + +task integrationTest(type: Test) { + testClassesDirs = sourceSets.integrationTest.output.classesDirs + classpath = sourceSets.integrationTest.runtimeClasspath +} + tasks.withType(Test) { testLogging { exceptionFormat = 'full' @@ -231,7 +255,30 @@ jacocoTestReport { } -project.tasks.release.dependsOn(project.tasks.build) +task buildItestImage(type: DockerBuildImage) { + inputDir = file('src/itest/docker-image') + tag = 'sshj/sshd-itest' +} + +task createItestContainer(type: DockerCreateContainer) { + dependsOn buildItestImage + targetImageId { buildItestImage.getImageId() } + portBindings = ['2222:22'] +} + +task startItestContainer(type: DockerStartContainer) { + dependsOn createItestContainer + targetContainerId { createItestContainer.getContainerId() } +} + +task stopItestContainer(type: DockerStopContainer) { + targetContainerId { createItestContainer.getContainerId() } +} + +project.tasks.integrationTest.dependsOn(startItestContainer) +project.tasks.integrationTest.finalizedBy(stopItestContainer) + +project.tasks.release.dependsOn([project.tasks.integrationTest, project.tasks.build]) project.tasks.release.finalizedBy(project.tasks.bintrayUpload) project.tasks.jacocoTestReport.dependsOn(project.tasks.test) project.tasks.check.dependsOn(project.tasks.jacocoTestReport) diff --git a/src/test/resources/Dockerfile b/src/itest/docker-image/Dockerfile similarity index 100% rename from src/test/resources/Dockerfile rename to src/itest/docker-image/Dockerfile diff --git a/src/itest/docker-image/id_rsa.pub b/src/itest/docker-image/id_rsa.pub new file mode 100644 index 00000000..6c50ee23 --- /dev/null +++ b/src/itest/docker-image/id_rsa.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAoZ9l6Tkm2aL1tSBy2yw4xU5s8BE9MfqS/4J7DzvsYJxF6oQmTIjmStuhH/CT7UjuDtKXdXZUsIhKtafiizxGO8kHSzKDeitpth2RSr8ddMzZKyD6RNs7MfsgjA3UTtrrSrCXEY6O43S2cnuJrWzkPxtwxaQ3zOvDbS2tiulzyq0VzYmuhA/a4CyuQtJBuu+P2oqmu6pU/VB6IzONpvBvYbNPsH1WDmP7zko5wHPihXPCliztspKxS4DRtOZ7BGXyvg44UmIy0Kf4jOkaBV/eCCA4qH7ZHz71/5ceMOpszPcNOEmLGGYhwI+P3OuGMpkrSAv1f8IY6R8spZNncP6UaQ== no-passphrase diff --git a/src/test/resources/test-container/ssh_host_ecdsa_key b/src/itest/docker-image/test-container/ssh_host_ecdsa_key similarity index 100% rename from src/test/resources/test-container/ssh_host_ecdsa_key rename to src/itest/docker-image/test-container/ssh_host_ecdsa_key diff --git a/src/test/resources/test-container/ssh_host_ecdsa_key.pub b/src/itest/docker-image/test-container/ssh_host_ecdsa_key.pub similarity index 100% rename from src/test/resources/test-container/ssh_host_ecdsa_key.pub rename to src/itest/docker-image/test-container/ssh_host_ecdsa_key.pub diff --git a/src/itest/groovy/com/hierynomus/sshj/IntegrationSpec.groovy b/src/itest/groovy/com/hierynomus/sshj/IntegrationSpec.groovy new file mode 100644 index 00000000..6675584f --- /dev/null +++ b/src/itest/groovy/com/hierynomus/sshj/IntegrationSpec.groovy @@ -0,0 +1,86 @@ +/* + * 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.DefaultConfig +import net.schmizz.sshj.SSHClient +import net.schmizz.sshj.transport.TransportException +import net.schmizz.sshj.transport.verification.PromiscuousVerifier +import net.schmizz.sshj.userauth.UserAuthException +import spock.lang.Specification + +class IntegrationSpec extends Specification { + private static final int DOCKER_PORT = 2222; + private static final String USERNAME = "sshj"; + private final static String SERVER_IP = System.getProperty("serverIP", "127.0.0.1"); + + def "should accept correct key"() { + given: + SSHClient sshClient = new SSHClient(new DefaultConfig()) + sshClient.addHostKeyVerifier("d3:6a:a9:52:05:ab:b5:48:dd:73:60:18:0c:3a:f0:a3") // test-containers/ssh_host_ecdsa_key's fingerprint + + when: + sshClient.connect(SERVER_IP, DOCKER_PORT) + + then: + sshClient.isConnected() + } + + def "should decline wrong key"() throws IOException { + given: + SSHClient sshClient = new SSHClient(new DefaultConfig()) + 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) + + then: + thrown(TransportException.class) + } + + def "should authenticate"() { + given: + SSHClient client = getConnectedClient() + + when: + client.authPublickey("sshj", "src/test/resources/id_rsa") + + then: + client.isAuthenticated() + } + + def "should not authenticate with wrong key"() { + given: + SSHClient client = getConnectedClient() + + when: + client.authPublickey("sshj", "src/test/resources/id_dsa") + + then: + thrown(UserAuthException.class) + !client.isAuthenticated() + } + + private static SSHClient getConnectedClient() throws IOException { + SSHClient sshClient = new SSHClient(new DefaultConfig()); + sshClient.addHostKeyVerifier(new PromiscuousVerifier()); + sshClient.connect(SERVER_IP, DOCKER_PORT); + + return sshClient; + } + + +} diff --git a/src/test/java/com/hierynomus/sshj/IntegrationTest.java b/src/test/java/com/hierynomus/sshj/IntegrationTest.java deleted file mode 100644 index 861b1a46..00000000 --- a/src/test/java/com/hierynomus/sshj/IntegrationTest.java +++ /dev/null @@ -1,82 +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 static org.hamcrest.MatcherAssert.assertThat; - -import java.io.File; -import java.io.IOException; - -import org.junit.Ignore; -import org.junit.Test; - -import net.schmizz.sshj.DefaultConfig; -import net.schmizz.sshj.SSHClient; -import net.schmizz.sshj.transport.TransportException; -import net.schmizz.sshj.transport.verification.OpenSSHKnownHosts; -import net.schmizz.sshj.transport.verification.PromiscuousVerifier; -import net.schmizz.sshj.userauth.UserAuthException; - -public class IntegrationTest { - - private static final int DOCKER_PORT = 2222; - private static final String USERNAME = "sshj"; - private final static String SERVER_IP = System.getProperty("serverIP", "127.0.0.1"); - - @Test @Ignore // Should only be enabled for testing against VM - public void shouldConnectVM() throws IOException { - SSHClient sshClient = new SSHClient(new DefaultConfig()); - sshClient.addHostKeyVerifier(new OpenSSHKnownHosts(new File("/Users/ajvanerp/.ssh/known_hosts"))); - sshClient.connect("172.16.37.147"); - sshClient.authPublickey("jeroen"); - assertThat("Is connected", sshClient.isAuthenticated()); - } - - @Test - public void shouldAcceptCorrectKey() throws IOException { - SSHClient sshClient = new SSHClient(new DefaultConfig()); - sshClient.addHostKeyVerifier("d3:6a:a9:52:05:ab:b5:48:dd:73:60:18:0c:3a:f0:a3"); // test-containers/ssh_host_ecdsa_key's fingerprint - sshClient.connect(SERVER_IP, DOCKER_PORT); - assertThat("Is connected", sshClient.isConnected()); - } - - @Test(expected = TransportException.class) - public void shouldDeclineWrongKey() throws IOException { - SSHClient sshClient = new SSHClient(new DefaultConfig()); - sshClient.addHostKeyVerifier("d4:6a:a9:52:05:ab:b5:48:dd:73:60:18:0c:3a:f0:a3"); - sshClient.connect(SERVER_IP, DOCKER_PORT); - } - - @Test - public void shouldConnect() throws IOException { - SSHClient sshClient = getConnectedClient(); - sshClient.authPublickey(USERNAME, "src/test/resources/id_rsa"); - assertThat("Is authenitcated", sshClient.isAuthenticated()); - } - - @Test(expected = UserAuthException.class) - public void shouldFailWithWrongKey() throws IOException { - getConnectedClient().authPublickey(USERNAME, "src/test/resources/id_dsa"); - } - - private SSHClient getConnectedClient() throws IOException { - SSHClient sshClient = new SSHClient(new DefaultConfig()); - sshClient.addHostKeyVerifier(new PromiscuousVerifier()); - sshClient.connect(SERVER_IP, DOCKER_PORT); - - return sshClient; - } -}