package org.testcontainers.containers;
import com.github.dockerjava.api.command.InspectContainerResponse;
import org.testcontainers.containers.traits.LinkableContainer;
import org.testcontainers.containers.traits.VncService;
import org.testcontainers.utility.TestcontainersConfiguration;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
/**
* 'Sidekick container' with the sole purpose of recording the VNC screen output from another container.
*/
public class VncRecordingSidekickContainer<SELF extends VncRecordingSidekickContainer<SELF, T>, T extends VncService & LinkableContainer> extends GenericContainer<SELF> {
private final T vncServiceContainer;
private final Path tempDir;
/**
* Create a sidekick container and link it to another container. The VNC output of that container will be recorded.
*
* @param vncServiceContainer the container whose screen should be recorded. This container must implement VncService and LinkableContainer.
*/
public VncRecordingSidekickContainer(T vncServiceContainer) {
super(TestcontainersConfiguration.getInstance().getVncRecordedContainerImage());
this.vncServiceContainer = vncServiceContainer;
try {
// Use a temporary volume directory that the container should record a file into
this.tempDir = createVolumeDirectory(true);
// flvrec.py needs to read the VNC password from a file
Path passwordFile = tempDir.resolve("password");
Files.write(passwordFile, vncServiceContainer.getPassword().getBytes());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
protected void containerIsStarting(InspectContainerResponse containerInfo) {
// do nothing
}
@Override
protected Integer getLivenessCheckPort() {
// no liveness check needed
return null;
}
@Override
protected void configure() {
addFileSystemBind(tempDir.toAbsolutePath().toString(), "/recording", BindMode.READ_WRITE);
addLink(vncServiceContainer, "vnchost");
setCommand(// the container entrypoint sets the executable name
"-o",
"/recording/screen.flv",
"-P",
"/recording/password",
"vnchost",
String.valueOf(vncServiceContainer.getPort()));
}
public Path getRecordingPath() {
return this.tempDir.resolve("screen.flv");
}
/**
* Stop the container and move the recording file to a suitable destination
* @param destination the location the recording should be moved to, overwriting any existing file
*/
public void stopAndRetainRecording(File destination) {
super.stop();
try {
Files.move(getRecordingPath(), destination.toPath(), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
throw new RuntimeException("Could not move recording file from " + getRecordingPath() + " to " + destination, e);
}
}
}