|
| 1 | +import io |
1 | 2 | import itertools |
2 | 3 | import logging |
3 | 4 | import re |
4 | 5 | import time |
5 | 6 | from datetime import timedelta |
| 7 | +from email.message import Message |
6 | 8 | from unittest.mock import Mock, patch |
| 9 | +from urllib.error import HTTPError |
7 | 10 |
|
8 | 11 | import pytest |
9 | 12 |
|
@@ -361,6 +364,31 @@ def test_from_url(self, url, expected_port, expected_path, expected_tls): |
361 | 364 | assert strategy._path == expected_path |
362 | 365 | assert strategy._tls is expected_tls |
363 | 366 |
|
| 367 | + @pytest.mark.parametrize( |
| 368 | + "status_codes,expected_result", |
| 369 | + [ |
| 370 | + ({503}, True), |
| 371 | + (set(), False), |
| 372 | + ], |
| 373 | + ids=[ |
| 374 | + "accepted_error_status_code", |
| 375 | + "unaccepted_error_status_code", |
| 376 | + ], |
| 377 | + ) |
| 378 | + @patch("testcontainers.core.wait_strategies.urlopen") |
| 379 | + def test_try_http_request_closes_http_error(self, mock_urlopen, status_codes, expected_result): |
| 380 | + """HTTPError holds the response's file object and must be closed (issue #1115).""" |
| 381 | + fp = io.BytesIO(b"error body") |
| 382 | + mock_urlopen.side_effect = HTTPError("http://localhost:8080/", 503, "Service Unavailable", Message(), fp) |
| 383 | + strategy = HttpWaitStrategy(8080) |
| 384 | + for code in status_codes: |
| 385 | + strategy.for_status_code(code) |
| 386 | + |
| 387 | + result = strategy._try_http_request("http://localhost:8080/", {}, None) |
| 388 | + |
| 389 | + assert result is expected_result |
| 390 | + assert fp.closed |
| 391 | + |
364 | 392 |
|
365 | 393 | class TestHealthcheckWaitStrategy: |
366 | 394 | """Test the HealthcheckWaitStrategy class.""" |
|
0 commit comments