|
1 | 1 | import enum |
2 | 2 | import errno |
3 | 3 | from http import client, HTTPStatus |
| 4 | +from http.client import HTTPConnection |
4 | 5 | import io |
| 6 | +from io import StringIO |
5 | 7 | import itertools |
6 | 8 | import os |
7 | 9 | import array |
8 | 10 | import re |
9 | 11 | import socket |
| 12 | +import sys |
10 | 13 | import threading |
11 | 14 |
|
12 | 15 | import unittest |
|
16 | 19 | from test import support |
17 | 20 | from test.support import os_helper |
18 | 21 | from test.support import socket_helper |
| 22 | +from unittest.mock import MagicMock |
19 | 23 |
|
20 | 24 | support.requires_working_socket(module=True) |
21 | 25 |
|
@@ -2525,5 +2529,75 @@ def _create_connection(address, timeout=None, source_address=None): |
2525 | 2529 | self.assertTrue(sock.file_closed) |
2526 | 2530 |
|
2527 | 2531 |
|
| 2532 | + |
| 2533 | +class TestHTTPSocketShutdown(TestCase): |
| 2534 | + def test_close_with_shutdown(self): |
| 2535 | + mock_socket = MagicMock() |
| 2536 | + mock_socket.close = MagicMock() |
| 2537 | + mock_socket.shutdown = MagicMock() |
| 2538 | + connection = HTTPConnection('www.example.com') |
| 2539 | + connection.sock = mock_socket |
| 2540 | + original_stderr = sys.stderr |
| 2541 | + sys.stderr = StringIO() |
| 2542 | + try: |
| 2543 | + connection.close(shutdown=True) |
| 2544 | + mock_socket.shutdown.assert_called_once_with(2) # SHUT_RDWR |
| 2545 | + mock_socket.close.assert_called_once() |
| 2546 | + error_output = sys.stderr.getvalue() |
| 2547 | + self.assertEqual(error_output, "") |
| 2548 | + finally: |
| 2549 | + sys.stderr = original_stderr |
| 2550 | + |
| 2551 | + def test_close_without_shutdown(self): |
| 2552 | + mock_socket = MagicMock() |
| 2553 | + mock_socket.close = MagicMock() |
| 2554 | + mock_socket.shutdown = MagicMock() |
| 2555 | + connection = HTTPConnection('www.example.com') |
| 2556 | + connection.sock = mock_socket |
| 2557 | + original_stderr = sys.stderr |
| 2558 | + sys.stderr = StringIO() |
| 2559 | + try: |
| 2560 | + connection.close(shutdown=False) |
| 2561 | + mock_socket.shutdown.assert_not_called() |
| 2562 | + mock_socket.close.assert_called_once() |
| 2563 | + error_output = sys.stderr.getvalue() |
| 2564 | + self.assertEqual(error_output, "") |
| 2565 | + finally: |
| 2566 | + sys.stderr = original_stderr |
| 2567 | + |
| 2568 | + def test_close_shutdown_error(self): |
| 2569 | + mock_socket = MagicMock() |
| 2570 | + mock_socket.close = MagicMock() |
| 2571 | + mock_socket.shutdown = MagicMock(side_effect=OSError("Shutdown error")) |
| 2572 | + connection = HTTPConnection('www.example.com') |
| 2573 | + connection.sock = mock_socket |
| 2574 | + original_stderr = sys.stderr |
| 2575 | + sys.stderr = StringIO() |
| 2576 | + try: |
| 2577 | + connection.close(shutdown=True) |
| 2578 | + mock_socket.shutdown.assert_called_once_with(2) # SHUT_RDWR |
| 2579 | + mock_socket.close.assert_called_once() |
| 2580 | + error_output = sys.stderr.getvalue() |
| 2581 | + self.assertIn("Socket shutdown error: Shutdown error", error_output) |
| 2582 | + finally: |
| 2583 | + sys.stderr = original_stderr |
| 2584 | + |
| 2585 | + def test_close_unexpected_error(self): |
| 2586 | + mock_socket = MagicMock() |
| 2587 | + mock_socket.close = MagicMock() |
| 2588 | + mock_socket.shutdown = MagicMock(side_effect=Exception("Unexpected error")) |
| 2589 | + connection = HTTPConnection('www.example.com') |
| 2590 | + connection.sock = mock_socket |
| 2591 | + original_stderr = sys.stderr |
| 2592 | + sys.stderr = StringIO() |
| 2593 | + try: |
| 2594 | + connection.close(shutdown=True) |
| 2595 | + mock_socket.shutdown.assert_called_once_with(2) # SHUT_RDWR |
| 2596 | + mock_socket.close.assert_called_once() |
| 2597 | + error_output = sys.stderr.getvalue() |
| 2598 | + self.assertIn("Unexpected error during socket shutdown: Unexpected error", error_output) |
| 2599 | + finally: |
| 2600 | + sys.stderr = original_stderr |
| 2601 | + |
2528 | 2602 | if __name__ == '__main__': |
2529 | 2603 | unittest.main(verbosity=2) |
0 commit comments