package io.jenkins.docker.connector; import com.nirima.jenkins.plugins.docker.DockerCloud; import com.nirima.jenkins.plugins.docker.DockerTemplate; import hudson.model.FreeStyleBuild; import hudson.model.FreeStyleProject; import hudson.model.Label; import hudson.model.Node; import hudson.model.Result; import hudson.model.TaskListener; import hudson.model.queue.QueueTaskFuture; import hudson.slaves.Cloud; import hudson.tasks.Shell; import hudson.util.StreamTaskListener; import io.jenkins.docker.DockerTransientNode; import io.jenkins.docker.client.DockerAPI; import org.apache.commons.lang3.SystemUtils; import org.hamcrest.number.OrderingComparison; import org.jenkinsci.plugins.docker.commons.credentials.DockerServerEndpoint; import org.junit.After; import org.junit.Assert; import org.junit.Assume; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Rule; import org.jvnet.hudson.test.JenkinsRule; import java.io.IOException; import java.nio.charset.Charset; import java.util.Collections; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; /** * @author <a href="mailto:[email protected]">Nicolas De Loof</a> */ public abstract class DockerComputerConnectorTest { protected static final String LABEL = "docker-agent"; protected static final String COMMON_IMAGE_USERNAME = "jenkins"; protected static final String COMMON_IMAGE_HOMEDIR = "/home/jenkins/agent"; protected static final String INSTANCE_CAP = "10"; private static int testNumber; private String cloudName; @BeforeClass public static void setUpClass() { testNumber=0; } @Before public void setUp() { testNumber++; cloudName = "DockerCloudFor" + this.getClass().getSimpleName() + testNumber; } @After public void cleanup() throws Exception { terminateAllDockerNodes(); final long startTimeMs = System.currentTimeMillis(); final Long maxWaitTimeMs = 60 * 1000L; final long initialWaitTime = 50; long currentWaitTime = initialWaitTime; while( dockerIsStillBusy()) { currentWaitTime = currentWaitTime * 2; Thread.sleep(currentWaitTime); terminateAllDockerNodes(); final long currentTimeMs = System.currentTimeMillis(); final Long elapsedTimeMs = currentTimeMs - startTimeMs; Assert.assertThat(elapsedTimeMs, OrderingComparison.lessThan(maxWaitTimeMs)); } } private void terminateAllDockerNodes() { final TaskListener tl = new StreamTaskListener(System.out, Charset.forName("UTF-8")); for( final Node n : j.jenkins.getNodes() ) { if( n instanceof DockerTransientNode ) { final DockerTransientNode dn = (DockerTransientNode)n; dn.terminate(tl); } } } private boolean dockerIsStillBusy() throws Exception { for( final Node n : j.jenkins.getNodes() ) { if( n instanceof DockerTransientNode ) { return true; } } for( final Cloud c : j.jenkins.clouds) { if( c instanceof DockerCloud) { DockerCloud cloud = (DockerCloud)c; for( final DockerTemplate t : cloud.getTemplates() ) { final int containersInProgress = cloud.countContainersInProgress(t); if( containersInProgress > 0 ) { return true; } } final int containersInDocker = cloud.countContainersInDocker(null); if( containersInDocker > 0 ) { return true; } } } return false; } @Rule public JenkinsRule j = new JenkinsRule(); protected void should_connect_agent(DockerTemplate template) throws IOException, ExecutionException, InterruptedException, TimeoutException { // FIXME on CI windows nodes don't have Docker4Windows Assume.assumeFalse(SystemUtils.IS_OS_WINDOWS); String dockerHost = SystemUtils.IS_OS_WINDOWS ? "tcp://localhost:2375" : "unix:///var/run/docker.sock"; DockerCloud cloud = new DockerCloud(cloudName, new DockerAPI(new DockerServerEndpoint(dockerHost, null)), Collections.singletonList(template)); j.jenkins.clouds.replaceBy(Collections.singleton(cloud)); final FreeStyleProject project = j.createFreeStyleProject("test-docker-ssh"); project.setAssignedLabel(Label.get(LABEL)); project.getBuildersList().add(new Shell("whoami")); final QueueTaskFuture<FreeStyleBuild> scheduledBuild = project.scheduleBuild2(0); try { final FreeStyleBuild build = scheduledBuild.get(60L, TimeUnit.SECONDS); Assert.assertTrue(build.getResult() == Result.SUCCESS); Assert.assertTrue(build.getLog().contains("jenkins")); } finally { scheduledBuild.cancel(true); } } }