psf / requests

A simple, yet elegant, HTTP library.
https://requests.readthedocs.io/en/latest/
Apache License 2.0
52.19k stars 9.33k forks source link

2.32.0 sdist is missing `tests/certs` #6706

Closed mgorny closed 6 months ago

mgorny commented 6 months ago

The requests 2.32.0 sdist tarball is missing files from tests/certs that are required for tests to pass.

Expected Result

Passing tests.

Actual Result

$ python -m pytest --showlocals
========================================================= test session starts =========================================================
platform linux -- Python 3.11.9, pytest-8.2.1, pluggy-1.5.0
rootdir: /tmp/requests-2.32.0
configfile: pyproject.toml
testpaths: tests
plugins: cov-5.0.0, httpbin-2.0.0
collected 606 items                                                                                                                   

tests/test_adapters.py .                                                                                                        [  0%]
tests/test_help.py ...                                                                                                          [  0%]
tests/test_hooks.py ...                                                                                                         [  1%]
tests/test_lowlevel.py ....................                                                                                     [  4%]
tests/test_packages.py ...                                                                                                      [  4%]
tests/test_requests.py ..............................127.0.0.1 - - [20/May/2024 21:31:33] "GET /get HTTP/1.1" 200 170
..........................127.0.0.1 - - [20/May/2024 21:31:33] "GET /cookies HTTP/1.1" 200 26
.............................127.0.0.1 - - [20/May/2024 21:31:37] "GET /basic-auth/user/pass HTTP/1.1" 401 0
....127.0.0.1 - - [20/May/2024 21:31:37] "GET /digest-auth/auth/user/pass/SHA-512 HTTP/1.1" 200 37
.127.0.0.1 - - [20/May/2024 21:31:37] "GET /digest-auth/auth/user/pass/SHA-512 HTTP/1.1" 401 0
.............. [ 22%]
...............s.............127.0.0.1 - - [20/May/2024 21:31:38] "POST /post HTTP/1.1" 200 222089
.........................................................................127.0.0.1 - - [20/May/2024 21:31:38] "GET /get HTTP/1.1" 200 222
......................... [ 43%]
.x........................................................................................127.0.0.1 - - [20/May/2024 21:32:08] "GET /bytes/20 HTTP/1.1" 500 59
...FFFF.                              [ 59%]
tests/test_structures.py ....................                                                                                   [ 62%]
tests/test_testserver.py ......s....                                                                                            [ 64%]
tests/test_utils.py ..s........................................................................................................ [ 82%]
............................................................................................sssssssssss.....s                   [100%]

============================================================== FAILURES ===============================================================
____________________________ TestPreparingURLs.test_different_connection_pool_for_tls_settings_verify_True ____________________________

self = <tests.test_requests.TestPreparingURLs object at 0x7f5f4dbf7410>

    def test_different_connection_pool_for_tls_settings_verify_True(self):
        def response_handler(sock):
            consume_socket_content(sock, timeout=0.5)
            sock.send(
                b"HTTP/1.1 200 OK\r\n"
                b"Content-Length: 18\r\n\r\n"
                b'\xff\xfe{\x00"\x00K0"\x00=\x00"\x00\xab0"\x00\r\n'
            )

        s = requests.Session()
        close_server = threading.Event()
>       server = TLSServer(
            handler=response_handler,
            wait_to_close_event=close_server,
            requests_to_handle=3,
            cert_chain="tests/certs/expired/server/server.pem",
            keyfile="tests/certs/expired/server/server.key",
        )

close_server = <threading.Event at 0x7f5f4d87f450: unset>
response_handler = <function TestPreparingURLs.test_different_connection_pool_for_tls_settings_verify_True.<locals>.response_handler at 0x7f5f4da47ba0>
s          = <requests.sessions.Session object at 0x7f5f4d8867d0>
self       = <tests.test_requests.TestPreparingURLs object at 0x7f5f4dbf7410>

tests/test_requests.py:2844: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <TLSServer(Thread-21, initial)>

    def __init__(
        self,
        *,
        handler=None,
        host="localhost",
        port=0,
        requests_to_handle=1,
        wait_to_close_event=None,
        cert_chain=None,
        keyfile=None,
        mutual_tls=False,
        cacert=None,
    ):
        super().__init__(
            handler=handler,
            host=host,
            port=port,
            requests_to_handle=requests_to_handle,
            wait_to_close_event=wait_to_close_event,
        )
        self.cert_chain = cert_chain
        self.keyfile = keyfile
        self.ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
>       self.ssl_context.load_cert_chain(self.cert_chain, keyfile=self.keyfile)
E       FileNotFoundError: [Errno 2] No such file or directory

__class__  = <class 'tests.testserver.server.TLSServer'>
cacert     = None
cert_chain = 'tests/certs/expired/server/server.pem'
handler    = <function TestPreparingURLs.test_different_connection_pool_for_tls_settings_verify_True.<locals>.response_handler at 0x7f5f4da47ba0>
host       = 'localhost'
keyfile    = 'tests/certs/expired/server/server.key'
mutual_tls = False
port       = 0
requests_to_handle = 3
self       = <TLSServer(Thread-21, initial)>
wait_to_close_event = <threading.Event at 0x7f5f4d87f450: unset>

tests/testserver/server.py:162: FileNotFoundError
____________________ TestPreparingURLs.test_different_connection_pool_for_tls_settings_verify_bundle_expired_cert _____________________

self = <tests.test_requests.TestPreparingURLs object at 0x7f5f4dbf6fd0>

    def test_different_connection_pool_for_tls_settings_verify_bundle_expired_cert(
        self,
    ):
        def response_handler(sock):
            consume_socket_content(sock, timeout=0.5)
            sock.send(
                b"HTTP/1.1 200 OK\r\n"
                b"Content-Length: 18\r\n\r\n"
                b'\xff\xfe{\x00"\x00K0"\x00=\x00"\x00\xab0"\x00\r\n'
            )

        s = requests.Session()
        close_server = threading.Event()
>       server = TLSServer(
            handler=response_handler,
            wait_to_close_event=close_server,
            requests_to_handle=3,
            cert_chain="tests/certs/expired/server/server.pem",
            keyfile="tests/certs/expired/server/server.key",
        )

close_server = <threading.Event at 0x7f5f4e8c5d90: unset>
response_handler = <function TestPreparingURLs.test_different_connection_pool_for_tls_settings_verify_bundle_expired_cert.<locals>.response_handler at 0x7f5f4d859d00>
s          = <requests.sessions.Session object at 0x7f5f4e8c4750>
self       = <tests.test_requests.TestPreparingURLs object at 0x7f5f4dbf6fd0>

tests/test_requests.py:2877: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <TLSServer(Thread-22, initial)>

    def __init__(
        self,
        *,
        handler=None,
        host="localhost",
        port=0,
        requests_to_handle=1,
        wait_to_close_event=None,
        cert_chain=None,
        keyfile=None,
        mutual_tls=False,
        cacert=None,
    ):
        super().__init__(
            handler=handler,
            host=host,
            port=port,
            requests_to_handle=requests_to_handle,
            wait_to_close_event=wait_to_close_event,
        )
        self.cert_chain = cert_chain
        self.keyfile = keyfile
        self.ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
>       self.ssl_context.load_cert_chain(self.cert_chain, keyfile=self.keyfile)
E       FileNotFoundError: [Errno 2] No such file or directory

__class__  = <class 'tests.testserver.server.TLSServer'>
cacert     = None
cert_chain = 'tests/certs/expired/server/server.pem'
handler    = <function TestPreparingURLs.test_different_connection_pool_for_tls_settings_verify_bundle_expired_cert.<locals>.response_handler at 0x7f5f4d859d00>
host       = 'localhost'
keyfile    = 'tests/certs/expired/server/server.key'
mutual_tls = False
port       = 0
requests_to_handle = 3
self       = <TLSServer(Thread-22, initial)>
wait_to_close_event = <threading.Event at 0x7f5f4e8c5d90: unset>

tests/testserver/server.py:162: FileNotFoundError
___________________ TestPreparingURLs.test_different_connection_pool_for_tls_settings_verify_bundle_unexpired_cert ____________________

self = <tests.test_requests.TestPreparingURLs object at 0x7f5f4dbf42d0>

    def test_different_connection_pool_for_tls_settings_verify_bundle_unexpired_cert(
        self,
    ):
        def response_handler(sock):
            consume_socket_content(sock, timeout=0.5)
            sock.send(
                b"HTTP/1.1 200 OK\r\n"
                b"Content-Length: 18\r\n\r\n"
                b'\xff\xfe{\x00"\x00K0"\x00=\x00"\x00\xab0"\x00\r\n'
            )

        s = requests.Session()
        close_server = threading.Event()
>       server = TLSServer(
            handler=response_handler,
            wait_to_close_event=close_server,
            requests_to_handle=3,
            cert_chain="tests/certs/valid/server/server.pem",
            keyfile="tests/certs/valid/server/server.key",
        )

close_server = <threading.Event at 0x7f5f4e9244d0: unset>
response_handler = <function TestPreparingURLs.test_different_connection_pool_for_tls_settings_verify_bundle_unexpired_cert.<locals>.response_handler at 0x7f5f4e7d0fe0>
s          = <requests.sessions.Session object at 0x7f5f4eaeffd0>
self       = <tests.test_requests.TestPreparingURLs object at 0x7f5f4dbf42d0>

tests/test_requests.py:2910: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <TLSServer(Thread-23, initial)>

    def __init__(
        self,
        *,
        handler=None,
        host="localhost",
        port=0,
        requests_to_handle=1,
        wait_to_close_event=None,
        cert_chain=None,
        keyfile=None,
        mutual_tls=False,
        cacert=None,
    ):
        super().__init__(
            handler=handler,
            host=host,
            port=port,
            requests_to_handle=requests_to_handle,
            wait_to_close_event=wait_to_close_event,
        )
        self.cert_chain = cert_chain
        self.keyfile = keyfile
        self.ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
>       self.ssl_context.load_cert_chain(self.cert_chain, keyfile=self.keyfile)
E       FileNotFoundError: [Errno 2] No such file or directory

__class__  = <class 'tests.testserver.server.TLSServer'>
cacert     = None
cert_chain = 'tests/certs/valid/server/server.pem'
handler    = <function TestPreparingURLs.test_different_connection_pool_for_tls_settings_verify_bundle_unexpired_cert.<locals>.response_handler at 0x7f5f4e7d0fe0>
host       = 'localhost'
keyfile    = 'tests/certs/valid/server/server.key'
mutual_tls = False
port       = 0
requests_to_handle = 3
self       = <TLSServer(Thread-23, initial)>
wait_to_close_event = <threading.Event at 0x7f5f4e9244d0: unset>

tests/testserver/server.py:162: FileNotFoundError
_________________________________ TestPreparingURLs.test_different_connection_pool_for_mtls_settings __________________________________

self = <tests.test_requests.TestPreparingURLs object at 0x7f5f4dbf4b90>

    def test_different_connection_pool_for_mtls_settings(self):
        client_cert = None

        def response_handler(sock):
            nonlocal client_cert
            client_cert = sock.getpeercert()
            consume_socket_content(sock, timeout=0.5)
            sock.send(
                b"HTTP/1.1 200 OK\r\n"
                b"Content-Length: 18\r\n\r\n"
                b'\xff\xfe{\x00"\x00K0"\x00=\x00"\x00\xab0"\x00\r\n'
            )

        s = requests.Session()
        close_server = threading.Event()
>       server = TLSServer(
            handler=response_handler,
            wait_to_close_event=close_server,
            requests_to_handle=2,
            cert_chain="tests/certs/expired/server/server.pem",
            keyfile="tests/certs/expired/server/server.key",
            mutual_tls=True,
            cacert="tests/certs/expired/ca/ca.crt",
        )

client_cert = None
close_server = <threading.Event at 0x7f5f4e81d410: unset>
response_handler = <function TestPreparingURLs.test_different_connection_pool_for_mtls_settings.<locals>.response_handler at 0x7f5f4da47600>
s          = <requests.sessions.Session object at 0x7f5f4e81fc50>
self       = <tests.test_requests.TestPreparingURLs object at 0x7f5f4dbf4b90>

tests/test_requests.py:2944: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <TLSServer(Thread-24, initial)>

    def __init__(
        self,
        *,
        handler=None,
        host="localhost",
        port=0,
        requests_to_handle=1,
        wait_to_close_event=None,
        cert_chain=None,
        keyfile=None,
        mutual_tls=False,
        cacert=None,
    ):
        super().__init__(
            handler=handler,
            host=host,
            port=port,
            requests_to_handle=requests_to_handle,
            wait_to_close_event=wait_to_close_event,
        )
        self.cert_chain = cert_chain
        self.keyfile = keyfile
        self.ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
>       self.ssl_context.load_cert_chain(self.cert_chain, keyfile=self.keyfile)
E       FileNotFoundError: [Errno 2] No such file or directory

__class__  = <class 'tests.testserver.server.TLSServer'>
cacert     = 'tests/certs/expired/ca/ca.crt'
cert_chain = 'tests/certs/expired/server/server.pem'
handler    = <function TestPreparingURLs.test_different_connection_pool_for_mtls_settings.<locals>.response_handler at 0x7f5f4da47600>
host       = 'localhost'
keyfile    = 'tests/certs/expired/server/server.key'
mutual_tls = True
port       = 0
requests_to_handle = 2
self       = <TLSServer(Thread-24, initial)>
wait_to_close_event = <threading.Event at 0x7f5f4e81d410: unset>

tests/testserver/server.py:162: FileNotFoundError
========================================================== warnings summary ===========================================================
tests/test_requests.py::TestRequests::test_set_basicauth[42-42]
tests/test_requests.py::TestRequests::test_set_basicauth[42-42]
  /tmp/requests-2.32.0/src/requests/auth.py:36: DeprecationWarning: Non-string usernames will no longer be supported in Requests 3.0.0. Please convert the object you've passed in (42) to a string or bytes object in the near future to avoid problems.
    warnings.warn(

tests/test_requests.py::TestRequests::test_set_basicauth[42-42]
tests/test_requests.py::TestRequests::test_set_basicauth[42-42]
  /tmp/requests-2.32.0/src/requests/auth.py:46: DeprecationWarning: Non-string passwords will no longer be supported in Requests 3.0.0. Please convert the object you've passed in (<class 'int'>) to a string or bytes object in the near future to avoid problems.
    warnings.warn(

tests/test_requests.py::TestRequests::test_set_basicauth[None-None]
tests/test_requests.py::TestRequests::test_set_basicauth[None-None]
  /tmp/requests-2.32.0/src/requests/auth.py:36: DeprecationWarning: Non-string usernames will no longer be supported in Requests 3.0.0. Please convert the object you've passed in (None) to a string or bytes object in the near future to avoid problems.
    warnings.warn(

tests/test_requests.py::TestRequests::test_set_basicauth[None-None]
tests/test_requests.py::TestRequests::test_set_basicauth[None-None]
  /tmp/requests-2.32.0/src/requests/auth.py:46: DeprecationWarning: Non-string passwords will no longer be supported in Requests 3.0.0. Please convert the object you've passed in (<class 'NoneType'>) to a string or bytes object in the near future to avoid problems.
    warnings.warn(

tests/test_utils.py::TestContentEncodingDetection::test_none
tests/test_utils.py::TestContentEncodingDetection::test_pragmas[<meta charset="UTF-8">]
tests/test_utils.py::TestContentEncodingDetection::test_pragmas[<meta http-equiv="Content-type" content="text/html;charset=UTF-8">]
tests/test_utils.py::TestContentEncodingDetection::test_pragmas[<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />]
tests/test_utils.py::TestContentEncodingDetection::test_pragmas[<?xml version="1.0" encoding="UTF-8"?>]
tests/test_utils.py::TestContentEncodingDetection::test_precedence
  /tmp/requests-2.32.0/src/requests/utils.py:494: DeprecationWarning: In requests 3.0, get_encodings_from_content will be removed. For more information, please see the discussion on issue #2266. (This warning should only appear once.)
    warnings.warn(

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
======================================================= short test summary info =======================================================
FAILED tests/test_requests.py::TestPreparingURLs::test_different_connection_pool_for_tls_settings_verify_True - FileNotFoundError: [Errno 2] No such file or directory
FAILED tests/test_requests.py::TestPreparingURLs::test_different_connection_pool_for_tls_settings_verify_bundle_expired_cert - FileNotFoundError: [Errno 2] No such file or directory
FAILED tests/test_requests.py::TestPreparingURLs::test_different_connection_pool_for_tls_settings_verify_bundle_unexpired_cert - FileNotFoundError: [Errno 2] No such file or directory
FAILED tests/test_requests.py::TestPreparingURLs::test_different_connection_pool_for_mtls_settings - FileNotFoundError: [Errno 2] No such file or directory
============================ 4 failed, 586 passed, 15 skipped, 1 xfailed, 14 warnings in 75.39s (0:01:15) =============================

Reproduction Steps

tar -xf requests-2.32.0.tar.gz
cd requests-2.32.0
pip install -e . -r requirements-dev.txt
python -m pytest --showlocals

System Information

$ python -m requests.help
{
  "chardet": {
    "version": null
  },
  "charset_normalizer": {
    "version": "3.3.2"
  },
  "cryptography": {
    "version": ""
  },
  "idna": {
    "version": "3.7"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.11.9"
  },
  "platform": {
    "release": "6.8.10-gentoo-dist",
    "system": "Linux"
  },
  "pyOpenSSL": {
    "openssl_version": "",
    "version": null
  },
  "requests": {
    "version": "2.32.0"
  },
  "system_ssl": {
    "version": "30200010"
  },
  "urllib3": {
    "version": "2.2.1"
  },
  "using_charset_normalizer": true,
  "using_pyopenssl": false
}
nateprewitt commented 6 months ago

Thanks for the report @mgorny. It looks like the test files from #6662 didn't end up in the MANIFEST.in. I'll take a look at getting that fixed asap.

nateprewitt commented 6 months ago

Fix is staged in #6708. You can track that for resolution. Thanks again!

nateprewitt commented 6 months ago

This should be resolved now with the release of 2.32.1.

mgorny commented 6 months ago

Thanks!