Skip to content

tests: Improve HTTP errors reporting

Add helper functions to check HTTP responses in tests implementation.

If an unexpected HTTP status code is encountered, the traceback that led to the error will be displayed in pytest report. See (fake error) example below:

==================================================================================================== FAILURES ====================================================================================================
___________________________________________________________________________________________ test_api_content_filetype ____________________________________________________________________________________________

api_client = <rest_framework.test.APIClient object at 0x7febef719da0>, indexer_data = <swh.web.tests.conftest._IndexerData object at 0x7febef7d74e0>

    @given(content())
>   def test_api_content_filetype(api_client, indexer_data, content):

swh/web/tests/api/views/test_content.py:21: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
swh/web/tests/api/views/test_content.py:26: in test_api_content_filetype
    rv = check_api_get_responses(api_client, url, status_code=200)
swh/web/tests/utils.py:110: in check_api_get_responses
    api_client, url, status_code, content_type="application/json"
swh/web/tests/utils.py:62: in check_http_get_response
    content_type=content_type,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

response = <Response status_code=500, "application/json">, status_code = 200, content_type = 'application/json'

    def _assert_http_response(
        response: HttpResponse, status_code: int, content_type: str
    ) -> HttpResponse:
    
        if isinstance(response, Response):
            drf_response = cast(Response, response)
            error_context = (
                drf_response.data.pop("traceback")
                if isinstance(drf_response.data, dict) and "traceback" in drf_response.data
                else drf_response.data
            )
        else:
            error_context = (
                getattr(response, "traceback")
                if hasattr(response, "traceback")
                else response.content
            )
    
>       assert response.status_code == status_code, error_context
E       AssertionError: Traceback (most recent call last):
E           File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/rest_framework/views.py", line 502, in dispatch
E             response = handler(request, *args, **kwargs)
E           File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/rest_framework/decorators.py", line 50, in handler
E             return func(*args, **kwargs)
E           File "/home/anlambert/swh/swh-environment/swh-web/swh/web/api/apiurls.py", line 92, in api_view_f
E             response = f(request, **kwargs)
E           File "/home/anlambert/swh/swh-environment/swh-web/swh/web/api/apidoc.py", line 348, in documented_view
E             raise exc
E           File "/home/anlambert/swh/swh-environment/swh-web/swh/web/api/apidoc.py", line 345, in documented_view
E             return {"data": f(request, **kwargs), "doc_data": doc_data}
E           File "/home/anlambert/swh/swh-environment/swh-web/swh/web/api/views/content.py", line 65, in api_content_filetype
E             request=request,
E           File "/home/anlambert/swh/swh-environment/swh-web/swh/web/api/views/utils.py", line 67, in api_lookup
E             res = lookup_fn(*args)
E           File "/home/anlambert/swh/swh-environment/swh-web/swh/web/common/archive.py", line 182, in lookup_content_filetype
E             filetype = _first_element(list(idx_storage.content_mimetype_get([sha1])))
E           File "/home/anlambert/swh/swh-environment/swh-indexer/swh/indexer/storage/in_memory.py", line 290, in content_mimetype_get
E             return self._mimetypes.get(ds)
E         NameError: name 'ds' is not defined
E         
E       assert 500 == 200
E        +  where 500 = <Response status_code=500, "application/json">.status_code

swh/web/tests/utils.py:34: AssertionError
____________________________________________________________________________________ test_api_content_filetype_sha_not_found _____________________________________________________________________________________

api_client = <rest_framework.test.APIClient object at 0x7febef719da0>

    def test_api_content_filetype_sha_not_found(api_client):
        unknown_content_ = random_content()
    
        url = reverse(
            "api-1-content-filetype", url_args={"q": "sha1:%s" % unknown_content_["sha1"]}
        )
>       rv = check_api_get_responses(api_client, url, status_code=404)

swh/web/tests/api/views/test_content.py:44: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
swh/web/tests/utils.py:110: in check_api_get_responses
    api_client, url, status_code, content_type="application/json"
swh/web/tests/utils.py:62: in check_http_get_response
    content_type=content_type,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

response = <Response status_code=500, "application/json">, status_code = 404, content_type = 'application/json'

    def _assert_http_response(
        response: HttpResponse, status_code: int, content_type: str
    ) -> HttpResponse:
    
        if isinstance(response, Response):
            drf_response = cast(Response, response)
            error_context = (
                drf_response.data.pop("traceback")
                if isinstance(drf_response.data, dict) and "traceback" in drf_response.data
                else drf_response.data
            )
        else:
            error_context = (
                getattr(response, "traceback")
                if hasattr(response, "traceback")
                else response.content
            )
    
>       assert response.status_code == status_code, error_context
E       AssertionError: Traceback (most recent call last):
E           File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/rest_framework/views.py", line 502, in dispatch
E             response = handler(request, *args, **kwargs)
E           File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/rest_framework/decorators.py", line 50, in handler
E             return func(*args, **kwargs)
E           File "/home/anlambert/swh/swh-environment/swh-web/swh/web/api/apiurls.py", line 92, in api_view_f
E             response = f(request, **kwargs)
E           File "/home/anlambert/swh/swh-environment/swh-web/swh/web/api/apidoc.py", line 348, in documented_view
E             raise exc
E           File "/home/anlambert/swh/swh-environment/swh-web/swh/web/api/apidoc.py", line 345, in documented_view
E             return {"data": f(request, **kwargs), "doc_data": doc_data}
E           File "/home/anlambert/swh/swh-environment/swh-web/swh/web/api/views/content.py", line 65, in api_content_filetype
E             request=request,
E           File "/home/anlambert/swh/swh-environment/swh-web/swh/web/api/views/utils.py", line 67, in api_lookup
E             res = lookup_fn(*args)
E           File "/home/anlambert/swh/swh-environment/swh-web/swh/web/common/archive.py", line 182, in lookup_content_filetype
E             filetype = _first_element(list(idx_storage.content_mimetype_get([sha1])))
E           File "/home/anlambert/swh/swh-environment/swh-indexer/swh/indexer/storage/in_memory.py", line 290, in content_mimetype_get
E             return self._mimetypes.get(ds)
E         NameError: name 'ds' is not defined
E         
E       assert 500 == 404
E        +  where 500 = <Response status_code=500, "application/json">.status_code

swh/web/tests/utils.py:34: AssertionError

Closes #2657 (closed)

Depends on !428 (closed)


Migrated from D4278 (view on Phabricator)

Merge request reports