Mysterious PyPy2 test case failure
pquentin opened this issue · comments
We just merged this new test from urllib3's master branch, and it fails on Travis with PyPy 2 with the following traceback:
____________ test_wrap_socket_given_ca_certs_no_load_default_certs _____________
Traceback (most recent call last):
File ".../urllib3/test/test_ssl.py", line 111, in test_wrap_socket_given_ca_certs_no_load_default_certs
ssl_.ssl_wrap_socket(sock, ca_certs="/tmp/fake-file")
File ".../urllib3/.tox/pypy/site-packages/urllib3/util/ssl_.py", line 382, in ssl_wrap_socket
context.load_verify_locations(ca_certs, ca_cert_dir)
File ".../urllib3/.tox/pypy/site-packages/mock/mock.py", line 1061, in __call__
_mock_self._mock_check_sig(*args, **kwargs)
File ".../urllib3/.tox/pypy/site-packages/mock/mock.py", line 209, in checksig
sig.bind(*args, **kwargs)
File ".../urllib3/.tox/pypy/site-packages/funcsigs/__init__.py", line 792, in bind
return args[0]._bind(args[1:], kwargs)
File ".../urllib3/.tox/pypy/site-packages/funcsigs/__init__.py", line 717, in _bind
raise TypeError(msg)
TypeError: 'cadata' parameter lacking default value
The traceback is also recorded in the commit message, and you can currently see it in the urllib3/urllib master builds. For example in https://travis-ci.org/urllib3/urllib3/jobs/572772982 (search for test_wrap_socket_given_ca_certs_no_load_default_certs).
Possibly relevant metadata:
$ python --version
Python 2.7.13 (ab0b9caf307db6592905a80b8faffd69b39005b8, Apr 30 2018, 08:21:35)
[PyPy 6.0.0 with GCC 7.2.0]
$ python -c "import ssl; print(ssl.OPENSSL_VERSION)"
OpenSSL 1.1.0h 27 Mar 2018
Anyway, the test fails with TypeError: 'cadata' parameter lacking default value
in an autospec mock. cadata
is a parameter that was added to SSLContext.load_verify_locations
in the standard library ssl
module in CPython 2.7.9. (CPython 2.7.9 was released in December 2014 and backported the whole ssl module from Python 3.4.)
For CPython < 2.7.9, urllib3 provides a custom SSLContext that only exposes the available options, so for example load_verify_locations
is called without cadata
. At some point, PyPy was probably just calling OpenSSL's SSL_CTX_load_verify_locations directly, but if I understand correctly then had to switch to the CPython implementation to support cadata
.
Okay, so, it looks like it's a mock/funcsigs bug they decided not to fix: testing-cabal/mock#438. What needs to be done here is to link to this issue and to the mock issue in the code, and I thus mark this as a good first issue!
To be clear, the idea here is to add something like this upstream (ie. urllib3/urllib3):
def test_wrap_socket_given_ca_certs_no_load_default_certs(monkeypatch):
+ if platform.python_implementation() == 'PyPy' and sys.version_info[0] == 2:
+ # https://github.com/testing-cabal/mock/issues/438
+ pytest.xfail("test is expected to fail with PyPy 2")
context = mock.create_autospec(ssl_.SSLContext)
context.load_default_certs = mock.Mock()
context.options = 0
We now have the fix, both upstream and here.