LogMessageWaitStrategy misses the required log lines when multiple containers are started

オープン
#3,186 コメント 2 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
42/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
停滞
技術スタック
docker, java, shell
領域
devops, testing-qa

調査の方向性

LogMessageWaitStrategy から始め、提供された Dockerfile と init script を使って standaloneTest を再現し、異なるワークロードを持つ 2 つのシーケンシャルなコンテナに焦点を当てます。各 strategy がコンテナログをどのように監視するかを追跡し、両方の startup checks が間欠的な timeout なしに “Initialization finished.” を確実に検出できることを完了条件とします。

索引モデルが issue の本文から書いたものです。

説明

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).

主要言語
Java
スター
8.7k
フォーク
1.9k
平均マージ
2日 17時間
マージ済み PR(30日)
9

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

testcontainers/testcontainers-java のほかの issue

testcontainers/testcontainers-java の issue をすべて見る

似ている issue

Java の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。