package com.github.dockerjava.netty.exec;
import static com.github.dockerjava.core.RemoteApiVersion.VERSION_1_22;
import static com.github.dockerjava.core.RemoteApiVersion.VERSION_1_23;
import static com.github.dockerjava.utils.TestUtils.getVersion;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.isEmptyString;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.containsString;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.security.SecureRandom;
import java.util.concurrent.TimeUnit;
import com.github.dockerjava.core.RemoteApiVersion;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.api.command.ExecCreateCmdResponse;
import com.github.dockerjava.core.command.ExecStartResultCallback;
import com.github.dockerjava.netty.AbstractNettyDockerClientTest;
@Test(groups = "integration")
public class ExecStartCmdExecTest extends AbstractNettyDockerClientTest {
@BeforeTest
public void beforeTest() throws Exception {
super.beforeTest();
}
@AfterTest
public void afterTest() {
super.afterTest();
}
@BeforeMethod
public void beforeMethod(Method method) {
super.beforeMethod(method);
}
@AfterMethod
public void afterMethod(ITestResult result) {
super.afterMethod(result);
}
@Test()
public void execStart() throws Exception {
String containerName = "generated_" + new SecureRandom().nextInt();
CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("top")
.withName(containerName).exec();
LOG.info("Created container {}", container.toString());
assertThat(container.getId(), not(isEmptyString()));
dockerClient.startContainerCmd(container.getId()).exec();
ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container.getId())
.withAttachStdout(true)
.withCmd("touch", "/execStartTest.log")
.exec();
dockerClient.execStartCmd(execCreateCmdResponse.getId())
.withDetach(false)
.exec(new ExecStartResultCallback(System.out, System.err))
.awaitCompletion();
InputStream response = dockerClient.copyArchiveFromContainerCmd(container.getId(), "/execStartTest.log").exec();
Boolean bytesAvailable = response.available() > 0;
assertTrue(bytesAvailable, "The file was not copied from the container.");
// read the stream fully. Otherwise, the underlying stream will not be closed.
String responseAsString = asString(response);
assertNotNull(responseAsString);
assertTrue(responseAsString.length() > 0);
}
@Test()
public void execStartAttached() throws Exception {
String containerName = "generated_" + new SecureRandom().nextInt();
CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999")
.withName(containerName).exec();
LOG.info("Created container {}", container.toString());
assertThat(container.getId(), not(isEmptyString()));
dockerClient.startContainerCmd(container.getId()).exec();
ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container.getId())
.withAttachStdout(true)
.withCmd("touch", "/execStartTest.log")
.exec();
dockerClient.execStartCmd(execCreateCmdResponse.getId())
.withDetach(false)
.exec(new ExecStartResultCallback(System.out, System.err))
.awaitCompletion();
InputStream response = dockerClient.copyArchiveFromContainerCmd(container.getId(), "/execStartTest.log").exec();
Boolean bytesAvailable = response.available() > 0;
assertTrue(bytesAvailable, "The file was not copied from the container.");
// read the stream fully. Otherwise, the underlying stream will not be closed.
String responseAsString = asString(response);
assertNotNull(responseAsString);
assertTrue(responseAsString.length() > 0);
}
@Test()
public void execStartAttachStdin() throws Exception {
String containerName = "generated_" + new SecureRandom().nextInt();
CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999")
.withName(containerName).exec();
LOG.info("Created container {}", container.toString());
assertThat(container.getId(), not(isEmptyString()));
dockerClient.startContainerCmd(container.getId()).exec();
InputStream stdin = new ByteArrayInputStream("STDIN\n".getBytes("UTF-8"));
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container.getId())
.withAttachStdout(true)
.withAttachStdin(true)
.withCmd("cat")
.exec();
boolean completed = dockerClient.execStartCmd(execCreateCmdResponse.getId())
.withDetach(false)
.withTty(true)
.withStdIn(stdin)
.exec(new ExecStartResultCallback(stdout, System.err))
.awaitCompletion(5, TimeUnit.SECONDS);
assertTrue(completed, "The process was not finished.");
assertEquals(stdout.toString("UTF-8"), "STDIN\n");
}
@Test()
public void execStartAttachStdinToShell() throws Exception {
String containerName = "generated_" + new SecureRandom().nextInt();
CreateContainerResponse container = dockerClient
.createContainerCmd("busybox")
.withCmd("sleep", "9999")
.withName(containerName)
.exec();
LOG.info("Created container {}", container.toString());
assertThat(container.getId(), not(isEmptyString()));
dockerClient.startContainerCmd(container.getId()).exec();
InputStream stdin = new ByteArrayInputStream("ls\n".getBytes());
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container.getId())
.withAttachStdout(true)
.withAttachStdin(true)
.withTty(false)
.withCmd("/bin/sh").exec();
dockerClient.execStartCmd(execCreateCmdResponse.getId())
.withDetach(false)
.withStdIn(stdin)
.exec(new ExecStartResultCallback(stdout, System.err))
.awaitCompletion();
assertThat(stdout.toString(), containsString("etc\n"));
}
@Test()
public void execStartNotAttachedStdin() throws Exception {
String containerName = "generated_" + new SecureRandom().nextInt();
CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999")
.withName(containerName).exec();
LOG.info("Created container {}", container.toString());
assertThat(container.getId(), not(isEmptyString()));
dockerClient.startContainerCmd(container.getId()).exec();
InputStream stdin = new ByteArrayInputStream("echo STDIN\n".getBytes());
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container.getId())
.withAttachStdout(true)
.withAttachStdin(false)
.withCmd("/bin/sh")
.exec();
boolean completed = dockerClient.execStartCmd(execCreateCmdResponse.getId())
.withDetach(false)
.withStdIn(stdin)
.exec(new ExecStartResultCallback(stdout, System.err))
.awaitCompletion(5, TimeUnit.SECONDS);
assertEquals(stdout.toString(), "");
if (getVersion(dockerClient).isGreaterOrEqual(VERSION_1_23)) {
assertFalse(completed, "The process was not finished.");
} else {
assertTrue(completed, "with v1.22 of the remote api the server closed the connection when no stdin " +
"was attached while exec create, so completed was true");
}
}
}