1+ # Assuming your existing test file has fixtures for the SSL objects
2+ import pytest
3+ import errno
4+ from OpenSSL import SSL
5+ from cheroot .ssl .pyopenssl import SSLConnection
6+
7+ @pytest .fixture
8+ def mock_ssl_context (mocker ):
9+ """Fixture providing a mock instance of SSL.Context."""
10+ return mocker .Mock (spec = SSL .Context )
11+
12+ @pytest .fixture
13+ def mock_ssl_conn_class (mocker ):
14+ """Fixture patching the SSL.Connection class constructor."""
15+ return mocker .patch ('OpenSSL.SSL.Connection' )
16+
17+ # (SysCallError errno, Expected Exception Type)
18+ ERROR_MAPPINGS = [
19+ (errno .EBADF , ConnectionError ),
20+ (errno .ECONNABORTED , ConnectionAbortedError ),
21+ (errno .ECONNREFUSED , ConnectionRefusedError ),
22+ (errno .ECONNRESET , ConnectionResetError ),
23+ (errno .ENOTCONN , ConnectionError ),
24+ (errno .EPIPE , BrokenPipeError ),
25+ (errno .ESHUTDOWN , BrokenPipeError ),
26+ ]
27+
28+ @pytest .mark .parametrize (
29+ 'simulated_errno, expected_exception' , ERROR_MAPPINGS
30+ )
31+ def test_close_morphs_syscall_error_correctly (
32+ mocker , mock_ssl_context , mock_ssl_conn_class ,
33+ simulated_errno , expected_exception
34+ ):
35+ # The SSLConnection object will now have a safe mock for self._ssl_conn
36+ conn = SSLConnection (mock_ssl_context )
37+
38+ # Define the specific OpenSSL error based on the parameter
39+ simulated_error = SSL .SysCallError (simulated_errno , 'Simulated connection error' )
40+
41+ # 4. Patch the 'close' method on the underlying MOCK object.
42+ # We retrieve the mock object that was placed in conn._ssl_conn during init.
43+ # The return value of the mocked SSL.Connection class is what conn._ssl_conn holds.
44+ underlying_mock = conn ._ssl_conn
45+
46+ mocker .patch .object (
47+ underlying_mock , 'close' ,
48+ side_effect = simulated_error
49+ )
50+
51+ # Assert the expected exception is raised based on the parameter
52+ with pytest .raises (expected_exception ) as excinfo :
53+ conn .close ()
54+
55+ # 6. Assert the original SysCallError is included in the new exception's cause
56+ assert excinfo .value .__cause__ is simulated_error
0 commit comments