mirror of https://github.com/apache/jclouds.git
[JCLOUDS-1084] Docker live tests fixed and made more robust
This commit is contained in:
parent
b6e20822d8
commit
3f1fe271ed
|
@ -38,6 +38,7 @@
|
|||
<test.docker.identity>${env.DOCKER_CERT_PATH}/cert.pem</test.docker.identity>
|
||||
<test.docker.credential>${env.DOCKER_CERT_PATH}/key.pem</test.docker.credential>
|
||||
<test.docker.cacert.path>${env.DOCKER_CERT_PATH}/ca.pem</test.docker.cacert.path>
|
||||
<test.docker.endpoint>${env.DOCKER_HOST}</test.docker.endpoint>
|
||||
<test.jclouds.trust-all-certs>false</test.jclouds.trust-all-certs>
|
||||
<jclouds.osgi.export>org.jclouds.docker*;version="${project.version}"</jclouds.osgi.export>
|
||||
<jclouds.osgi.import>
|
||||
|
@ -151,7 +152,7 @@
|
|||
</goals>
|
||||
<configuration>
|
||||
<name>test.docker.endpoint</name>
|
||||
<value>${env.DOCKER_HOST}</value>
|
||||
<value>${test.docker.endpoint}</value>
|
||||
<regex>tcp</regex>
|
||||
<replacement>https</replacement>
|
||||
<failIfNoMatch>false</failIfNoMatch>
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.jclouds.Constants;
|
|||
import org.jclouds.apis.BaseApiLiveTest;
|
||||
import org.jclouds.compute.config.ComputeServiceProperties;
|
||||
import org.jclouds.docker.DockerApi;
|
||||
import org.jclouds.docker.internal.DockerTestUtils;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||
|
@ -46,7 +47,7 @@ import com.google.inject.Module;
|
|||
public class BaseDockerApiLiveTest extends BaseApiLiveTest<DockerApi> {
|
||||
|
||||
protected static final String DEFAULT_IMAGE = "alpine";
|
||||
protected static final String DEFAULT_TAG = "3.2";
|
||||
protected static final String DEFAULT_TAG = "3.3";
|
||||
protected static final String ALPINE_IMAGE_TAG = String.format("%s:%s", DEFAULT_IMAGE, DEFAULT_TAG);
|
||||
|
||||
|
||||
|
@ -54,6 +55,17 @@ public class BaseDockerApiLiveTest extends BaseApiLiveTest<DockerApi> {
|
|||
provider = "docker";
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes Docker image if it's present on the Docker host.
|
||||
*
|
||||
* @param imageName
|
||||
* image to be deleted (must be not-<code>null</code>)
|
||||
* @see DockerTestUtils#removeImageIfExists(DockerApi, String)
|
||||
*/
|
||||
protected void removeImageIfExists(String imageName) {
|
||||
DockerTestUtils.removeImageIfExists(api, imageName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterable<Module> setupModules() {
|
||||
return ImmutableSet.<Module>of(getLoggingModule(), new SshjSshClientModule());
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.jclouds.docker.compute;
|
|||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
|
||||
|
@ -32,9 +33,8 @@ import org.jclouds.docker.compute.strategy.DockerComputeServiceAdapter;
|
|||
import org.jclouds.docker.domain.Container;
|
||||
import org.jclouds.docker.domain.Image;
|
||||
import org.jclouds.docker.options.CreateImageOptions;
|
||||
import org.jclouds.docker.options.DeleteImageOptions;
|
||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||
import org.testng.annotations.AfterGroups;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -48,7 +48,7 @@ import com.google.inject.Module;
|
|||
public class DockerComputeServiceAdapterLiveTest extends BaseDockerApiLiveTest {
|
||||
|
||||
private static final String SSHABLE_IMAGE = "kwart/alpine-ext";
|
||||
private static final String SSHABLE_IMAGE_TAG = "3.2-ssh";
|
||||
private static final String SSHABLE_IMAGE_TAG = "3.3-ssh";
|
||||
private Image defaultImage;
|
||||
|
||||
private DockerComputeServiceAdapter adapter;
|
||||
|
@ -68,6 +68,14 @@ public class DockerComputeServiceAdapterLiveTest extends BaseDockerApiLiveTest {
|
|||
assertNotNull(defaultImage);
|
||||
}
|
||||
|
||||
@AfterClass(alwaysRun = true)
|
||||
protected void tearDown() {
|
||||
if (guest != null) {
|
||||
adapter.destroyNode(guest.getNode().id() + "");
|
||||
}
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DockerApi create(Properties props, Iterable<Module> modules) {
|
||||
Injector injector = newBuilder().modules(modules).overrides(props).buildInjector();
|
||||
|
@ -83,7 +91,7 @@ public class DockerComputeServiceAdapterLiveTest extends BaseDockerApiLiveTest {
|
|||
Template template = templateBuilder.imageId(defaultImage.id()).build();
|
||||
|
||||
DockerTemplateOptions options = template.getOptions().as(DockerTemplateOptions.class);
|
||||
options.env(ImmutableList.of("ROOT_PASS=password"));
|
||||
options.env(ImmutableList.of("ROOT_PASSWORD=password"));
|
||||
guest = adapter.createNodeWithGroupEncodedIntoName(group, name, template);
|
||||
assertEquals(guest.getNodeId(), guest.getNode().id());
|
||||
}
|
||||
|
@ -97,17 +105,6 @@ public class DockerComputeServiceAdapterLiveTest extends BaseDockerApiLiveTest {
|
|||
}
|
||||
}
|
||||
|
||||
@AfterGroups(groups = "live")
|
||||
protected void tearDown() {
|
||||
if (guest != null) {
|
||||
adapter.destroyNode(guest.getNode().id() + "");
|
||||
}
|
||||
if (defaultImage != null) {
|
||||
api.getImageApi().deleteImage(defaultImage.id(), DeleteImageOptions.Builder.force(true));
|
||||
}
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterable<Module> setupModules() {
|
||||
return ImmutableSet.<Module>of(getLoggingModule(), new SshjSshClientModule());
|
||||
|
|
|
@ -17,15 +17,15 @@
|
|||
package org.jclouds.docker.compute;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.jclouds.compute.options.TemplateOptions.Builder.runAsRoot;
|
||||
import static org.jclouds.compute.options.RunScriptOptions.Builder.wrapInInitScript;
|
||||
import static org.jclouds.docker.internal.DockerTestUtils.consumeStreamSilently;
|
||||
import static org.jclouds.docker.internal.DockerTestUtils.removeImageIfExists;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.jclouds.compute.RunNodesException;
|
||||
import org.jclouds.compute.domain.ExecResponse;
|
||||
|
@ -104,8 +104,9 @@ public class SshToCustomPortLiveTest extends BaseComputeServiceContextLiveTest {
|
|||
@Test(dependsOnMethods = "testImageCreated")
|
||||
public void testCustomPortSsh() throws RunNodesException {
|
||||
final DockerTemplateOptions options = DockerTemplateOptions.Builder
|
||||
.commands("/usr/sbin/dropbear", "-E", "-F", "-p", String.valueOf(SSH_PORT)).overrideLoginUser("root")
|
||||
.overrideLoginPassword("screencast").blockOnPort(SSH_PORT, 30).networkMode("host");
|
||||
.env("SSH_PORT=" + SSH_PORT, "ROOT_PASSWORD=screencast")
|
||||
.overrideLoginUser("root").overrideLoginPassword("screencast")
|
||||
.blockOnPort(SSH_PORT, 30).networkMode("host");
|
||||
|
||||
final Template template = view.getComputeService().templateBuilder().imageId(image.id()).options(options).build();
|
||||
|
||||
|
@ -115,8 +116,7 @@ public class SshToCustomPortLiveTest extends BaseComputeServiceContextLiveTest {
|
|||
.getOnlyElement(view.getComputeService().createNodesInGroup("ssh-test", 1, template));
|
||||
|
||||
nodeId = node.getId();
|
||||
ExecResponse response = view.getComputeService().runScriptOnNode(nodeId, "echo hello",
|
||||
runAsRoot(false).wrapInInitScript(false));
|
||||
ExecResponse response = view.getComputeService().runScriptOnNode(nodeId, "sh -c 'echo hello && sleep 0.2'", wrapInInitScript(false));
|
||||
assertThat(response.getOutput().trim()).endsWith("hello");
|
||||
} finally {
|
||||
if (nodeId != null)
|
||||
|
@ -133,8 +133,11 @@ public class SshToCustomPortLiveTest extends BaseComputeServiceContextLiveTest {
|
|||
@BeforeClass(groups = { "integration", "live" })
|
||||
public void setupContext() {
|
||||
super.setupContext();
|
||||
|
||||
final String tag = toTag(IMAGE_REPOSITORY, IMAGE_TAG_1);
|
||||
|
||||
removeImageIfExists(api(), tag);
|
||||
removeImageIfExists(api(), toTag(IMAGE_REPOSITORY, IMAGE_TAG_2));
|
||||
|
||||
BuildOptions options = BuildOptions.Builder.tag(tag).verbose(false).nocache(false);
|
||||
InputStream buildImageStream;
|
||||
try {
|
||||
|
@ -154,8 +157,8 @@ public class SshToCustomPortLiveTest extends BaseComputeServiceContextLiveTest {
|
|||
*/
|
||||
@AfterClass(alwaysRun = true)
|
||||
protected void tearDown() {
|
||||
consumeStreamSilently(api().getImageApi().deleteImage(toTag(IMAGE_REPOSITORY, IMAGE_TAG_1)));
|
||||
consumeStreamSilently(api().getImageApi().deleteImage(toTag(IMAGE_REPOSITORY, IMAGE_TAG_2)));
|
||||
removeImageIfExists(api(), toTag(IMAGE_REPOSITORY, IMAGE_TAG_1));
|
||||
removeImageIfExists(api(), toTag(IMAGE_REPOSITORY, IMAGE_TAG_2));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -188,29 +191,6 @@ public class SshToCustomPortLiveTest extends BaseComputeServiceContextLiveTest {
|
|||
return view.unwrapApi(DockerApi.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read all data from given InputStream and throw away all the bits.
|
||||
*
|
||||
* @param is
|
||||
*/
|
||||
private static void consumeStreamSilently(InputStream is) {
|
||||
char[] tmpBuff = new char[8 * 1024];
|
||||
// throw everything away
|
||||
InputStreamReader isr = new InputStreamReader(is);
|
||||
|
||||
try {
|
||||
try {
|
||||
while (isr.read(tmpBuff) > -1) {
|
||||
// empty
|
||||
}
|
||||
} finally {
|
||||
isr.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
java.util.logging.Logger.getAnonymousLogger().log(Level.WARNING, "Error ocured during reading InputStream.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenate repository and tag name (if provided) in Docker format.
|
||||
*
|
||||
|
@ -221,4 +201,5 @@ public class SshToCustomPortLiveTest extends BaseComputeServiceContextLiveTest {
|
|||
private static String toTag(String repo, String tag) {
|
||||
return repo + (tag != null ? ":" + tag : "");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -67,9 +67,6 @@ public class ContainerApiLiveTest extends BaseDockerApiLiveTest {
|
|||
api.getContainerApi().removeContainer(container.id(), RemoveContainerOptions.Builder.force(true));
|
||||
}
|
||||
}
|
||||
if (image != null) {
|
||||
api.getImageApi().deleteImage(ALPINE_IMAGE_TAG);
|
||||
}
|
||||
}
|
||||
|
||||
public void testCreateContainer() throws IOException, InterruptedException {
|
||||
|
|
|
@ -51,6 +51,8 @@ import com.google.common.collect.Iterables;
|
|||
@Test(groups = "live", testName = "MiscApiLiveTest", singleThreaded = true)
|
||||
public class MiscApiLiveTest extends BaseDockerApiLiveTest {
|
||||
|
||||
private static final String IMAGE_TEST_TAG = "jclouds-test-test-build-image";
|
||||
|
||||
private static String imageId;
|
||||
|
||||
private Container container = null;
|
||||
|
@ -105,14 +107,19 @@ public class MiscApiLiveTest extends BaseDockerApiLiveTest {
|
|||
|
||||
@Test
|
||||
public void testBuildImageFromDockerfile() throws IOException, InterruptedException, URISyntaxException {
|
||||
BuildOptions options = BuildOptions.Builder.tag("jclouds-test-test-build-image").verbose(false).nocache(false);
|
||||
removeImageIfExists(IMAGE_TEST_TAG);
|
||||
BuildOptions options = BuildOptions.Builder.tag(IMAGE_TEST_TAG).verbose(false).nocache(true);
|
||||
InputStream buildImageStream = api().build(tarredDockerfile(), options);
|
||||
String buildStream = consumeStream(buildImageStream);
|
||||
Iterable<String> splitted = Splitter.on("\n").split(buildStream.replace("\r", "").trim());
|
||||
String lastStreamedLine = Iterables.getLast(splitted).trim();
|
||||
String rawImageId = Iterables.getLast(Splitter.on("Successfully built ").split(lastStreamedLine));
|
||||
imageId = rawImageId.substring(0, 11);
|
||||
assertNotNull(imageId);
|
||||
try {
|
||||
Iterable<String> splitted = Splitter.on("\n").split(buildStream.replace("\r", "").trim());
|
||||
String lastStreamedLine = Iterables.getLast(splitted).trim();
|
||||
String rawImageId = Iterables.getLast(Splitter.on("Successfully built ").split(lastStreamedLine));
|
||||
imageId = rawImageId.substring(0, 11);
|
||||
assertNotNull(imageId);
|
||||
} finally {
|
||||
removeImageIfExists(IMAGE_TEST_TAG);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -168,7 +175,6 @@ public class MiscApiLiveTest extends BaseDockerApiLiveTest {
|
|||
assertEquals(execInspect.exitCode(), 2);
|
||||
}
|
||||
|
||||
|
||||
private MiscApi api() {
|
||||
return api.getMiscApi();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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 org.jclouds.docker.internal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.jclouds.docker.DockerApi;
|
||||
import org.jclouds.docker.features.ImageApi;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
/**
|
||||
* Utility methods shared by Docker tests.
|
||||
*/
|
||||
public class DockerTestUtils {
|
||||
|
||||
/**
|
||||
* Read all data from given {@link InputStream} and throw away all the bits.
|
||||
* If an {@link IOException} occurs, it's not propagated to user. The given InputStream is closed after the read.
|
||||
*
|
||||
* @param is InputStream instance (may be null)
|
||||
*/
|
||||
public static void consumeStreamSilently(InputStream is) {
|
||||
if (is == null) {
|
||||
return;
|
||||
}
|
||||
char[] tmpBuff = new char[8 * 1024];
|
||||
// throw everything away
|
||||
InputStreamReader isr = new InputStreamReader(is);
|
||||
try {
|
||||
try {
|
||||
while (isr.read(tmpBuff) > -1) {
|
||||
// empty
|
||||
}
|
||||
} finally {
|
||||
isr.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
java.util.logging.Logger.getAnonymousLogger().log(Level.WARNING, "Error ocured during reading InputStream.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes Docker image if it's present on the Docker host. Docker Image API
|
||||
* is used to inspect and remove image (({@link ImageApi#deleteImage(String)}
|
||||
* method).
|
||||
*
|
||||
* @param dockerApi
|
||||
* DockerApi instance (must be not-<code>null</code>)
|
||||
* @param imageName
|
||||
* image to be deleted (must be not-<code>null</code>)
|
||||
*/
|
||||
public static void removeImageIfExists(DockerApi dockerApi, String imageName) {
|
||||
Preconditions.checkNotNull(dockerApi, "DockerApi instance has to be provided");
|
||||
Preconditions.checkNotNull(imageName, "Docker image name has to be provided");
|
||||
final ImageApi imageApi = dockerApi.getImageApi();
|
||||
if (null != imageApi.inspectImage(imageName)) {
|
||||
consumeStreamSilently(imageApi.deleteImage(imageName));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,19 +16,5 @@
|
|||
#
|
||||
|
||||
|
||||
FROM alpine:3.2
|
||||
FROM kwart/alpine-ext:3.3-ssh
|
||||
MAINTAINER JClouds Dev <dev@jclouds.apache.org>
|
||||
|
||||
ENV DROPBEAR_CONF=/etc/dropbear
|
||||
|
||||
RUN apk add --update dropbear \
|
||||
&& mkdir -p ${DROPBEAR_CONF} \
|
||||
&& dropbearkey -t dss -f ${DROPBEAR_CONF}/dropbear_dss_host_key \
|
||||
&& dropbearkey -t rsa -f ${DROPBEAR_CONF}/dropbear_rsa_host_key -s 2048 \
|
||||
&& dropbearkey -t ecdsa -f ${DROPBEAR_CONF}/dropbear_ecdsa_host_key
|
||||
|
||||
RUN echo 'root:screencast' | chpasswd
|
||||
|
||||
EXPOSE 22
|
||||
|
||||
CMD ["/usr/sbin/dropbear", "-E", "-F"]
|
||||
|
|
Loading…
Reference in New Issue