Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

configure pytest strict #71

Merged
merged 4 commits into from
Mar 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 4 additions & 8 deletions pytest_httpbin/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,14 @@

@pytest.fixture(scope="session")
def httpbin(request):
server = serve.Server(application=httpbin_app)
server.start()
request.addfinalizer(server.stop)
return server
with serve.Server(application=httpbin_app) as server:
yield server


@pytest.fixture(scope="session")
def httpbin_secure(request):
server = serve.SecureServer(application=httpbin_app)
server.start()
request.addfinalizer(server.stop)
return server
with serve.SecureServer(application=httpbin_app) as server:
yield server


@pytest.fixture(scope="session", params=["http", "https"])
Expand Down
27 changes: 19 additions & 8 deletions pytest_httpbin/serve.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,16 @@ def finish_request(self, request, client_address):
"""
request.settimeout(1.0)
try:
ssock = ssl.wrap_socket(
request,
keyfile=os.path.join(CERT_DIR, "key.pem"),
certfile=os.path.join(CERT_DIR, "cert.pem"),
server_side=True,
suppress_ragged_eofs=False,
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain(
os.path.join(CERT_DIR, "cert.pem"),
os.path.join(CERT_DIR, "key.pem"),
)
self.base_environ["HTTPS"] = "yes"
self.RequestHandlerClass(ssock, client_address, self)
with context.wrap_socket(
request, server_side=True, suppress_ragged_eofs=False
) as ssock:
self.base_environ["HTTPS"] = "yes"
self.RequestHandlerClass(ssock, client_address, self)
except Exception as e:
print("pytest-httpbin server hit an exception serving request: %s" % e)
print("attempting to ignore so the rest of the tests can run")
Expand Down Expand Up @@ -106,6 +107,16 @@ def __del__(self):
def start(self):
self._thread.start()

def __enter__(self):
self.start()
return self

def __exit__(self, *args, **kwargs):
self.stop()
suppress_exc = self._server.__exit__(*args, **kwargs)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixes #55

self._thread.join()
return suppress_exc

def __add__(self, other):
return self.url + other

Expand Down
6 changes: 6 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,9 @@ disable-noqa = True
max-line-length = 88
extend-ignore =
E203, # whitespace before : is not PEP8 compliant (& conflicts with black)


[tool:pytest]
addopts = --strict-config --strict-markers
filterwarnings = error
xfail_strict = true
37 changes: 31 additions & 6 deletions tests/test_server.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import contextlib
import os
import re
import socket

import pytest
import requests
import requests.exceptions
from httpbin import app as httpbin_app
from util import get_raw_http_response

Expand Down Expand Up @@ -40,9 +43,33 @@ def test_server_should_be_http_1_1(httpbin):


def test_dont_crash_on_certificate_problems(httpbin_secure):
with pytest.raises(Exception):
with pytest.raises(requests.exceptions.SSLError):
# this request used to hang
requests.get(httpbin_secure + "/get", verify=True, cert=__file__)

# and this request would never happen
requests.get(
httpbin_secure + "/get",
verify=True,
)


def test_dont_crash_on_handshake_timeout(httpbin_secure, capsys):
with socket.socket() as sock:
sock.connect((httpbin_secure.host, httpbin_secure.port))
# this request used to hang
assert sock.recv(1) == b""

assert (
re.match(
r"pytest-httpbin server hit an exception serving request: .* The "
"handshake operation timed out\nattempting to ignore so the rest "
"of the tests can run\n",
capsys.readouterr().out,
)
is not None
)

# and this request would never happen
requests.get(
httpbin_secure + "/get",
Expand All @@ -68,6 +95,7 @@ def test_fixed_port_environment_variables(protocol):
# just have different port to avoid adrress already in use
# if the second test run too fast after the first one (happens on pypy)
port = 12345 + len(protocol)
server = contextlib.nullcontext()

try:
envvar_original = os.environ.get(envvar, None)
Expand All @@ -76,10 +104,7 @@ def test_fixed_port_environment_variables(protocol):
assert server.port == port
finally:
# if we don't do this, it blocks:
try:
server.start()
server.stop()
except UnboundLocalError:
with server:
pass

# restore the original environ:
Expand Down
20 changes: 10 additions & 10 deletions tests/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ def get_raw_http_response(host, port, path):
]

# Connect to the server
s = socket.socket()
s.connect((host, port))
with socket.socket() as s:
s.connect((host, port))

# Send an HTTP request
s.send(CRLF.join(request))
# Send an HTTP request
s.send(CRLF.join(request))

# Get the response (in several parts, if necessary)
response = b""
buffer = s.recv(4096)
while buffer:
response += buffer
# Get the response (in several parts, if necessary)
response = b""
buffer = s.recv(4096)
while buffer:
response += buffer
buffer = s.recv(4096)

return response
return response
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ envlist = py37, py38, py39, py310, pypy3
wheel = True
wheel_build_env = build
extras = test
commands = pytest -v -s
commands = pytest -v -s {posargs}

[testenv:build]
# empty environment to build universal wheel once per tox invocation
Expand Down