testcontainers / testcontainers/testcontainers-java

LogMessageWaitStrategy misses the required log lines when multiple containers are started

Abierto
#3,186 2 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Lenguaje dominante
Java
Estrellas
8.7k
Forks
1.9k
Merge medio
2 d 17 h
PR fusionados (30 d)
9

Descripción

I start a custom database container and then I run a second container which executes a bunch of SQL scripts to initialize the database (these scripts usually run in less than a second) and exits. For both of these containers I use LogMessageWaitStrategy to check that (a) the database is ready; (b) the initialization scripts finished running and the initialization was successful.

The problem: the second container almost always (but not absolutely every time) does not pass the startup check, though the required log line is printed to the log.

After a while I came up with a synthetic test case which does not depend on our custom images.

The Dockerfile:

FROM alpine
COPY init /
CMD ["/init"]

The init script:

#!/bin/sh

if [ "$HANG" = 'true' ]
then
    echo 'I will start and work hard for a long while.'
else
    echo 'I will perform some quick initialization and quit.'
fi

# Emulate some workload before the initialization finishes.
sleep 0.1

echo "Initialization finished."

# Hang to emulate some workload running after initialization.
[ "$HANG" = 'true' ] && sleep inf || true

After building the image with the tag test I run the following test case:

@Test
public void standaloneTest() {
    new GenericContainer<>("test")
        .withEnv("HANG", "true")
        .waitingFor(new LogMessageWaitStrategy()
                .withRegEx(".*Initialization finished.*"))
        .start();

    new GenericContainer<>("test")
        .waitingFor(new LogMessageWaitStrategy()
                .withRegEx(".*Initialization finished.*"))
        .start();
}

The test hangs on the second start() for a while and then fails with Not ready yet exception, though I see the correct log lines reported by Testcontainers just before the exception (Log output from the failed container).

Few things to consider:

  • a single container using the test image always passes the startup check successfully disregarding how quickly it starts and how quickly it exits;
  • a problem appears only when both containers use LogMessageWaitStrategy;
  • increasing the sleep duration in the script decreases the chances of the issue: sleep 0.3 makes the issue less frequent and sleep 1 removes it almost completely;
  • Thread.sleep(1000) inserted between the start()s seems to be a workaround, but it is not reliable and the issue still reproduces, though rarely.

I use Testcontainers 1.14.3. The environment varies; on different machines (all running different flavors of Linux) the issue has a different chance to fire (it seems that the chances are higher on more powerful and fast hardware).

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza con LogMessageWaitStrategy y reproduce standaloneTest utilizando el Dockerfile y el script de inicialización proporcionados, centrándote en dos contenedores secuenciales con cargas de trabajo diferentes. Rastrea cómo cada estrategia observa los logs de los contenedores y define como completado que ambas comprobaciones de inicio detecten de forma fiable “Initialization finished.” sin el timeout intermitente.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
docker, java, shell
Área
devops, testing-qa
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
42/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.