Skip to content

Commit

Permalink
Several cleanups for integration tests (reuse bravado client, use res…
Browse files Browse the repository at this point in the history
…ponse() API), use separate repos for autopep8 and flake8 pre-commit hooks
  • Loading branch information
sjaensch committed Feb 21, 2019
1 parent 9ad344e commit 0d46d8d
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 45 deletions.
19 changes: 12 additions & 7 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ repos:
- repo: git://github.com/pre-commit/pre-commit-hooks
sha: v1.1.1
hooks:
- id: autopep8-wrapper
language_version: python3.6
args:
- -i
- --ignore=E309,E501
- id: check-added-large-files
language_version: python3.6
- id: check-byte-order-marker
Expand All @@ -23,15 +18,25 @@ repos:
language_version: python3.6
args:
- --remove
- id: flake8
language_version: python3.6
- id: name-tests-test
language_version: python3.6
- id: trailing-whitespace
language_version: python3.6
- id: requirements-txt-fixer
language_version: python3.6
files: requirements-dev.txt
- repo: git://github.com/pre-commit/mirrors-autopep8
rev: v1.4.3
hooks:
- id: autopep8
args: ['-i', '--ignore=E309,E501']
language_version: python3.6
- repo: https://gitlab.com/pycqa/flake8.git
rev: 3.7.6
hooks:
- id: flake8
exclude: ^docs
language_version: python3.6
- repo: https://github.com/asottile/pyupgrade
sha: v1.2.0
hooks:
Expand Down
100 changes: 62 additions & 38 deletions tests/integration/integration_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import io
import os.path
import time
from asyncio import run_coroutine_threadsafe

import pytest
from bravado import requests_client
Expand All @@ -10,11 +11,13 @@
from bravado.exception import HTTPBadRequest
from bravado.exception import HTTPInternalServerError
from bravado.exception import HTTPNotFound
from bravado_core.model import Model

from bravado_asyncio import http_client
from bravado_asyncio import thread_loop


@pytest.fixture(params=[http_client.AsyncioClient, requests_client.RequestsClient])
@pytest.fixture(scope='module', params=[http_client.AsyncioClient, requests_client.RequestsClient])
def swagger_client(integration_server, request):
# Run all integration tests twice, once with our AsyncioClient and once again with the RequestsClient
# to make sure they both behave the same.
Expand All @@ -24,27 +27,26 @@ def swagger_client(integration_server, request):
return SwaggerClient.from_url(
spec_url,
http_client=request.param(),
config={'also_return_response': True},
)


def test_get_query_args(swagger_client):
result, response = swagger_client.user.loginUser(
response = swagger_client.user.loginUser(
username='asyncio',
password='p%s&wörd?',
invalidate_sessions=True,
).result(timeout=1)
).response(timeout=1)

assert result == 'success'
assert response.result == 'success'
# let's make sure we can access the headers through the response object
assert response.headers['X-Rate-Limit'] == '4711'
assert response.headers['X-Expires-After'] == 'Expiration date'
assert response.metadata.headers['X-Rate-Limit'] == '4711'
assert response.metadata.headers['X-Expires-After'] == 'Expiration date'


def test_param_multi(swagger_client):
result, response = swagger_client.pet.getPetsByIds(
result = swagger_client.pet.getPetsByIds(
petIds=[23, 42],
).result(timeout=1)
).response(timeout=1).result

assert len(result) == 2
assert result[0]._as_dict() == {
Expand All @@ -69,24 +71,24 @@ def test_response_headers(swagger_client):
"""Make sure response headers are returned in the same format across HTTP clients. Namely,
make sure names and values are str, and that it's possible to access headers in a
case-insensitive manner."""
_, response = swagger_client.pet.getPetById(petId=42).result(timeout=1)
assert response.headers['content-type'] == response.headers['Content-Type'] == 'application/json; charset=utf-8'
metadata = swagger_client.pet.getPetById(petId=42).response(timeout=1).metadata
assert metadata.headers['content-type'] == metadata.headers['Content-Type'] == 'application/json; charset=utf-8'


def test_post_form_data(swagger_client):
result, _ = swagger_client.pet.updatePetWithForm(
result = swagger_client.pet.updatePetWithForm(
petId=12,
name='Vivi',
status='sold',
userId=42,
photoUrls=('http://first.url?param1=value1&param2=ß%$', 'http://second.url'),
).result(timeout=1)
).response(timeout=1).result
assert result is None


def test_put_json_body(swagger_client):
# the test server would raise a 404 if the data didn't match
result, _ = swagger_client.pet.updatePet(
result = swagger_client.pet.updatePet(
body={
'id': 42,
'category': {
Expand All @@ -96,76 +98,95 @@ def test_put_json_body(swagger_client):
'photoUrls': [],
'status': 'sold',
},
).result(timeout=1)
).response(timeout=1).result

assert result is None


def test_delete_query_args(swagger_client):
result, _ = swagger_client.pet.deletePet(petId=5).result(timeout=1)
result = swagger_client.pet.deletePet(petId=5).response(timeout=1).result
assert result is None


def test_post_file_upload(swagger_client):
with open(os.path.join(os.path.dirname(__file__), '../../testing/sample.jpg'), 'rb') as image:
result, _ = swagger_client.pet.uploadFile(
result = swagger_client.pet.uploadFile(
petId=42,
file=image,
userId=12,
).result(timeout=1)
).response(timeout=1).result

assert result is None


def test_post_file_upload_stream_no_name(swagger_client):
with open(os.path.join(os.path.dirname(__file__), '../../testing/sample.jpg'), 'rb') as image:
bytes_io = io.BytesIO(image.read()) # BytesIO has no attribute 'name'
result, _ = swagger_client.pet.uploadFile(
result = swagger_client.pet.uploadFile(
petId=42,
file=bytes_io,
userId=12,
).result(timeout=1)
).response(timeout=1).result

assert result is None


def test_multiple_requests(swagger_client):
fut1 = swagger_client.store.getInventory()
fut2 = swagger_client.pet.deletePet(petId=5)

assert fut1.response().result == {}
assert fut2.response().result is None


def test_get_msgpack(swagger_client):
result, response = swagger_client.pet.getPetsByName(petName='lili').result(timeout=1)
response = swagger_client.pet.getPetsByName(petName='lili').response(timeout=1)

assert len(result) == 1
assert result[0]._as_dict() == {
assert len(response.result) == 1
assert response.result[0]._as_dict() == {
'id': 42,
'name': 'Lili',
'photoUrls': [],
'category': None,
'status': None,
'tags': None,
}
assert response.headers['Content-Type'] == 'application/msgpack'
assert response.metadata.headers['Content-Type'] == 'application/msgpack'


def test_server_400(swagger_client):
with pytest.raises(HTTPBadRequest):
swagger_client.user.loginUser(username='not', password='correct').result(timeout=1)
swagger_client.user.loginUser(username='not', password='correct').response(timeout=1)


def test_server_404(swagger_client):
with pytest.raises(HTTPNotFound):
swagger_client.pet.getPetById(petId=5).result(timeout=1)
swagger_client.pet.getPetById(petId=5).response(timeout=1)


def test_server_500(swagger_client):
with pytest.raises(HTTPInternalServerError):
swagger_client.pet.deletePet(petId=42).result(timeout=1)
swagger_client.pet.deletePet(petId=42).response(timeout=1)


def test_timeout_on_future(swagger_client):
def test_timeout_request_options(swagger_client):
other_future = swagger_client.pet.getPetById(petId=42)
with pytest.raises(BravadoTimeoutError):
bravado_future = swagger_client.store.getInventory()
bravado_future.result(timeout=0.1)
bravado_future = swagger_client.store.getInventory(_request_options={'timeout': 0.1})
bravado_future.response(timeout=None)

# make sure the exception doesn't disrupt the other request
assert isinstance(other_future.response(timeout=1).result, Model)

@pytest.mark.xfail(reason='Timeout exception is not raised reliably for AsyncioClient')
def test_timeout_request_options(swagger_client):

def test_timeout_on_future(swagger_client):
other_future = swagger_client.pet.getPetById(petId=42)
with pytest.raises(BravadoTimeoutError):
bravado_future = swagger_client.store.getInventory(_request_options={'timeout': 0.1})
bravado_future.result(timeout=None)
bravado_future = swagger_client.store.getInventory()
bravado_future.response(timeout=0.1)

# make sure the exception doesn't disrupt the other request
assert isinstance(other_future.response(timeout=1).result, Model)


@pytest.mark.xfail(reason='Execution time is not always below 2 seconds especially for Python 3.5')
Expand All @@ -177,11 +198,14 @@ def test_client_from_asyncio(integration_server):
# recreate the separate event loop and client session for the HTTP client so we start with a clean slate
# this is important since we measure the time this test takes, and the test_timeout() tasks might
# interfere with it
http_client.client_session.close()
loop = thread_loop.get_thread_loop()
if http_client.client_session:
run_coroutine_threadsafe(http_client.client_session.close(), loop)
http_client.client_session = None
# not going to properly shut down the running loop, this will be cleaned up on exit
http_client.loop = None
thread_loop.event_loop = None

# get a second event loop running in the current thread; we'll use this one to run the test
loop = asyncio.get_event_loop()
start_time = time.time()
loop.run_until_complete(_test_asyncio_client(integration_server))
Expand Down Expand Up @@ -225,10 +249,10 @@ async def _test_asyncio_client(integration_server):
result = await future
assert result == 42

result1 = future1.result(timeout=5)
result1 = future1.response(timeout=5).result
assert result1 == {}

result2 = future2.result(timeout=5)
result2 = future2.response(timeout=5).result
assert result2 == {}

return True

0 comments on commit 0d46d8d

Please sign in to comment.