Ejecutar comandos dentro de los contenedores
Algunos contenedores Docker proporcionan herramientas de interfaz de línea de
comandos (CLI) para realizar acciones. Puedes utilizar
container.execInContainer(String...) para ejecutar cualquier comando disponible
dentro de un contenedor en ejecución.
Ejemplo: Crear un bucket de S3 en LocalStack
El módulo LocalStack emula los servicios de AWS. Para probar las cargas de archivos en S3, crea un bucket antes de ejecutar las pruebas:
package com.testcontainers.demo;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.testcontainers.containers.localstack.LocalStackContainer.Service.S3;
import java.io.IOException;
import java.net.URI;
import java.util.List;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.localstack.LocalStackContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.Bucket;
@Testcontainers
class LocalStackTest {
static final String bucketName = "mybucket";
@Container
static LocalStackContainer localStack = new LocalStackContainer(
DockerImageName.parse("localstack/localstack:3.4.0")
);
@BeforeAll
static void beforeAll() throws IOException, InterruptedException {
localStack.execInContainer("awslocal", "s3", "mb", "s3://" + bucketName);
org.testcontainers.containers.Container.ExecResult execResult =
localStack.execInContainer("awslocal", "s3", "ls");
String stdout = execResult.getStdout();
int exitCode = execResult.getExitCode();
assertTrue(stdout.contains(bucketName));
assertEquals(0, exitCode);
}
@Test
void shouldListBuckets() {
URI s3Endpoint = localStack.getEndpointOverride(S3);
StaticCredentialsProvider credentialsProvider =
StaticCredentialsProvider.create(
AwsBasicCredentials.create(
localStack.getAccessKey(),
localStack.getSecretKey()
)
);
S3Client s3 = S3Client
.builder()
.endpointOverride(s3Endpoint)
.credentialsProvider(credentialsProvider)
.region(Region.of(localStack.getRegion()))
.build();
List<String> s3Buckets = s3
.listBuckets()
.buckets()
.stream()
.map(Bucket::name)
.toList();
assertTrue(s3Buckets.contains(bucketName));
}
}La llamada execInContainer("awslocal", "s3", "mb", "s3://mybucket") ejecuta la
herramienta de CLI awslocal (provista por la imagen de LocalStack) para crear un
bucket de S3.
Puedes capturar la salida (stdout) y el código de salida (exit code) de cualquier comando:
Container.ExecResult execResult =
localStack.execInContainer("awslocal", "s3", "ls");
String stdout = execResult.getStdout();
int exitCode = execResult.getExitCode();NoteLos métodos
withCopyFileToContainer()yexecInContainer()se heredan deGenericContainer, por lo que están disponibles para todos los módulos de Testcontainers.
Resumen
- Utiliza
withCopyFileToContainer()para colocar archivos de inicialización dentro de los contenedores antes de que se inicien. - Utiliza
execInContainer()para ejecutar comandos dentro de contenedores en ejecución para tareas de configuración como la creación de buckets, temas (topics) o colas.