Compartir comentarios
Las respuestas se generan en base a la documentación.

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();
Note

Los métodos withCopyFileToContainer() y execInContainer() se heredan de GenericContainer, 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.

Lecturas adicionales