testcontainers / testcontainers/testcontainers-python

Bug: file descriptor leak in HttpWaitStrategy

オープン 初心者向け
#1,115 コメント 0 件 リアクション 1 件 担当者 0 名 GitHub で見る

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

主要言語
Python
スター
2.3k
フォーク
386
平均マージ
4時間 40分
マージ済み PR(30日)
1

説明

Describe the bug

When using an HttpWaitStrategy in DockerContainer.waiting_for and the container image respond with an error code, the underlying HttpError is not correctly handled, leaking a file descriptor.

To Reproduce

Example with the https://hub.docker.com/r/typesense/typesense image, but should work with any image providing a HTTP server that takes a few seconds to start:

# mre.py
from testcontainers.core.container import DockerContainer
from testcontainers.core.wait_strategies import HttpWaitStrategy

print("starting")
with (
    DockerContainer("typesense/typesense:30.2", command="--data-dir /home --api-key=whatever --enable-cors")
    .with_exposed_ports(8108)
    .waiting_for(HttpWaitStrategy(8108, "/health").for_status_code(200))
):
    print("ok")
$ python -Werror::ResourceWarning mre.py
starting
Exception ignored while calling deallocator <function _TemporaryFileCloser.__del__ at 0x101984880>:
Traceback (most recent call last):
  File "/Users/loic/.local/share/uv/python/cpython-3.14.4-macos-aarch64-none/lib/python3.14/tempfile.py", line 484, in __del__
    _warnings.warn(self.warn_message, ResourceWarning)
ResourceWarning: Implicitly cleaning up <HTTPError 503: ''>
ok

Root Cause / fix

The issue is in https://github.com/testcontainers/testcontainers-python/blob/5c70d540e0df919e2de77ce8cc75b5c50cd772e7/src/testcontainers/core/wait_strategies.py#L428-L437

HttpError holds a reference to a (temporary) file storing the HTTP response, so it must be handled in a context manager to safely clean the file when the error is discarded.

Fixed MRE:

# mre.py
from contextlib import nullcontext
from typing import Union
from urllib.error import HTTPError, URLError

from testcontainers.core.container import DockerContainer
from testcontainers.core.wait_strategies import HttpWaitStrategy

class _FixedHttpWaitStrategy(HttpWaitStrategy):
    def _handle_http_error(self, error: Union[URLError, HTTPError]) -> bool:
        with error if isinstance(error, HTTPError) else nullcontext(error):
            return super()._handle_http_error(error)

print("starting")
with (
    DockerContainer("typesense/typesense:30.2", command="--data-dir /home --api-key=whatever --enable-cors")
    .with_exposed_ports(8108)
    .waiting_for(_FixedHttpWaitStrategy(8108, "/health").for_status_code(200))
):
    print("ok")

Runtime environment

  • MacOS 26.6.2
  • Python 3.14.4
  • testcontainers 4.14.2

I can work on a PR if you'd like!

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

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

はじめの一歩

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

調査の方向性

issue がリーク箇所として特定している src/testcontainers/core/wait_strategies.py の HttpWaitStrategy._handle_http_error 周辺から始めます。提供されている MRE を -Werror::ResourceWarning とともに typesense/typesense イメージに対して実行し、再現します。HTTP エラーレスポンスが安全にクリーンアップされ、MRE が ResourceWarning なしで完了すれば完了です。

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

評価

技術スタック
docker, python
領域
testing-qa
issue の種類
バグ
難易度
2/5
見積もり時間
1〜3時間
活発さ
活発
明瞭さ
明確に書かれている
初心者へのやさしさ
88/100

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

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