/******************************************************************************* * Copyright (c) 2012-2017 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.plugin.docker.machine.integration; import org.eclipse.che.api.core.model.machine.Command; import org.eclipse.che.api.core.util.LineConsumer; import org.eclipse.che.api.machine.server.exception.MachineException; import org.eclipse.che.api.machine.server.model.impl.CommandImpl; import org.eclipse.che.plugin.docker.client.DockerApiVersionPathPrefixProvider; import org.eclipse.che.plugin.docker.client.DockerConnector; import org.eclipse.che.plugin.docker.client.DockerConnectorConfiguration; import org.eclipse.che.plugin.docker.client.DockerConnectorProvider; import org.eclipse.che.plugin.docker.client.DockerRegistryAuthResolver; import org.eclipse.che.plugin.docker.client.InitialAuthConfig; import org.eclipse.che.plugin.docker.client.connection.DockerConnectionFactory; import org.eclipse.che.plugin.docker.client.helper.DefaultNetworkFinder; import org.eclipse.che.plugin.docker.client.json.ContainerConfig; import org.eclipse.che.plugin.docker.client.json.ContainerCreated; import org.eclipse.che.plugin.docker.client.params.CreateContainerParams; import org.eclipse.che.plugin.docker.client.params.RemoveContainerParams; import org.eclipse.che.plugin.docker.client.params.StartContainerParams; import org.eclipse.che.plugin.docker.client.params.StopContainerParams; import org.eclipse.che.plugin.docker.machine.DockerProcess; import org.mockito.Mock; import org.mockito.testng.MockitoTestNGListener; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Listeners; import org.testng.annotations.Test; import static org.mockito.Mockito.when; import java.io.IOException; import java.net.URI; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; /** * @author Alexander Garagatyi */ @Listeners(MockitoTestNGListener.class) public class DockerProcessTest { private DockerConnectorConfiguration dockerConnectorConfiguration; private DockerConnector docker; private String container; private AtomicInteger pidGenerator = new AtomicInteger(1); @Mock private DockerConnectorProvider dockerConnectorProvider; @BeforeMethod public void setUp() throws Exception { dockerConnectorConfiguration = new DockerConnectorConfiguration(new InitialAuthConfig(), new DefaultNetworkFinder()); docker = new DockerConnector(dockerConnectorConfiguration, new DockerConnectionFactory(dockerConnectorConfiguration), new DockerRegistryAuthResolver(null, null), new DockerApiVersionPathPrefixProvider("1.18")); final ContainerCreated containerCreated = docker.createContainer( CreateContainerParams.create(new ContainerConfig().withImage("ubuntu") .withCmd("tail", "-f", "/dev/null"))); container = containerCreated.getId(); docker.startContainer(StartContainerParams.create(containerCreated.getId())); when(dockerConnectorProvider.get()).thenReturn(docker); } @AfterMethod public void tearDown() throws Exception { if (container != null) { docker.stopContainer(StopContainerParams.create(container) .withTimeout(2, TimeUnit.SECONDS)); docker.removeContainer(RemoveContainerParams.create(container) .withForce(true) .withRemoveVolumes(true)); } } /** * This test requires TCP access to docker API to get timeout exception.<br> * If default access to docker is UNIX socket try to reconfigure docker connector for this test.<br> * This test may fail if system doesn't allow such access. */ @Test(expectedExceptions = MachineException.class, expectedExceptionsMessageRegExp = "Command output read timeout is reached. Process is still running and has id \\d+ inside machine") public void shouldThrowErrorWithRealPIDIfSocketTimeoutExceptionHappens() throws Exception { DockerConnectorConfiguration dockerConnectorConfiguration = this.dockerConnectorConfiguration; DockerConnector docker = this.docker; if ("unix".equals(dockerConnectorConfiguration.getDockerDaemonUri().getScheme())) { // access through unix socket - reconfigure to use tcp dockerConnectorConfiguration = new DockerConnectorConfiguration(new URI("http://localhost:2375"), null, new InitialAuthConfig(), new DefaultNetworkFinder()); docker = new DockerConnector(dockerConnectorConfiguration, new DockerConnectionFactory(dockerConnectorConfiguration), new DockerRegistryAuthResolver(null, null), new DockerApiVersionPathPrefixProvider("")); } Command command = new CommandImpl("tailf", "tail -f /dev/null", "mvn"); final DockerProcess dockerProcess = new DockerProcess(dockerConnectorProvider, command, container, "outputChannel", "/tmp/chetests", pidGenerator.incrementAndGet()); dockerProcess.start(new SOUTLineConsumer()); } static class SOUTLineConsumer implements LineConsumer { @Override public void writeLine(String line) throws IOException { System.out.println(line); } @Override public void close() throws IOException { } } }