I am completely new to falcon and decided to introduce myself to it by following the tutorial from the official documentation. Sadly, I am stuck in chapter Refactoring for testability because one of the test fails (while it shouldn't according to the tutorial)!
After refactoring look/app.py and updating tests/test_app.py, when I run pytest tests I get the following message:
============================= test session starts ==============================
platform linux -- Python 3.6.7, pytest-4.6.2, py-1.8.0, pluggy-0.12.0
rootdir: /home/adrien/Storage/Tutorials/falcon_look
collected 2 items
tests/test_app.py .F [100%]
=================================== FAILURES ===================================
_______________________________ test_post_image ________________________________
client = <falcon.testing.client.TestClient object at 0x7ff3219d0e48>
mock_store = <MagicMock id='140682217762656'>
def test_post_image(client, mock_store):
file_name = 'fake-image-name.xyz'
# We need to know what ImageStore method will be used
mock_store.save.return_value = file_name
image_content_type = 'image/xyz'
response = client.simulate_post(
'/images',
body=b'some-fake-bytes',
headers={'content-type': image_content_type}
)
assert response.status == falcon.HTTP_CREATED
assert response.headers['location'] == '/images/{}'.format(file_name)
saver_call = mock_store.save.call_args
# saver_call is a unittest.mock.call tuple. It's first element is a
# tuple of positional arguments supplied when calling the mock.
> assert isinstance(saver_call[0][0], falcon.request_helpers.BoundedStream)
E AssertionError: assert False
E + where False = isinstance(<wsgiref.validate.InputWrapper object at 0x7ff3219cb128>, <class 'falcon.request_helpers.BoundedStream'>)
E + where <class 'falcon.request_helpers.BoundedStream'> = <module 'falcon.request_helpers' from '/home/adrien/.local/share/virtualenvs/falcon_look-GS2-stg2/lib/python3.6/site-packages/falcon/request_helpers.cpython-36m-x86_64-linux-gnu.so'>.BoundedStream
E + where <module 'falcon.request_helpers' from '/home/adrien/.local/share/virtualenvs/falcon_look-GS2-stg2/lib/python3.6/site-packages/falcon/request_helpers.cpython-36m-x86_64-linux-gnu.so'> = falcon.request_helpers
tests/test_app.py:66: AssertionError
====================== 1 failed, 1 passed in 0.07 seconds ======================
I have very little understanding of how the test works - could use a few more lines about that in the tutorial by the way ;-) - so I am not able to figure where the problem comes from.
I copy pasted the code from the tutorial to avoid mistakes on my side. Could it be a mistake in the tutorial code?
Or something to do with the versions of the packages I use? I created a Pipenv virtual environment for the tuto, in which I run pytest. Here is my Pipfile.lock.
Hi :wave:,
Thanks for using Falcon. The large amount of time and effort needed to
maintain the project and develop new features is not sustainable without
the generous financial support of community members like you.
Please consider helping us secure the future of the Falcon framework with a
one-time or recurring donation.
Thank you for your support!
HI @monsieurTut, I am having the same problem.
Could you figure out a solution?
Hi @faustind, no I just skipped this test :-/
Hi @faustind and @monsieurTut !
I agree this is indeed embarrassing, very obviously we have to automate testing of these documentation examples and tutorial steps.
Some work has already been done by our fantastic contributors at PyCon US 2019 sprints, see, for instance:
I have created a broader umbrella issue out there as well: https://github.com/falconry/falcon/issues/1423
Just getting back to the particular issue you have at hand, yes, just comment out that specific test for now.
It is testing that the request stream is an instance of BoundedStream, which is no longer true in Falcon 2.0 due to this breaking change:
The
falcon.Request.streamattribute is no longer wrapped in a bounded stream when Falcon detects that it is running on the wsgiref server. If you need to normalize stream semantics between wsgiref and a production WSGI server,bounded_streammay be used instead.
I've just come across this issue in a set of falcon tests which hadn't been run for quite a few months, where any reference to streamor stream.read() in the application was raising the AssertionError.
I can confirm that changing all references to stream to bounded_stream passed the wsgiref validation.
I wish i'd found this issue before the headscratching trial and error rather than after it ;)
As deployed in gunicorn the application was working fine without the change, and it did feel like servicing the code to fit the tests. I would _really_ recommend revisiting the behaviour of the wsgiref validation in the falcon testing interface
Hello!
I have raised a PR which updates the test to check for the stream to be an instance of wsgiref.validate.InputWrapper
If anyone else has this problem before (and if) it's merged, here are the changes:
https://github.com/falconry/falcon/pull/1558/files
Hi again @monsieurTut @faustind @cravindra and @metazool !
I'm going to close this issue since it has been resolved as part of https://github.com/falconry/falcon/pull/1558 by @cravindra at least for our master branch. You can find the latest bleeding-edge docs here: https://falcon.readthedocs.io/en/latest/user/tutorial.html#refactoring-for-testability
Furthermore, I added this to Travis so we make sure the tests actually pass: https://github.com/falconry/falcon/pull/1611
@metazool looking at our issues, I can indeed confirm that the stream vs bounded_stream change was probably wreaking most havoc among all breaking changes in Falcon 2.0.
However, Falcon strives for being a minimalist framework without too many unnecessary layers of abstraction, and as you have observed as well, stream works just fine on Gunicorn. As such, I think it makes much sense to keep the stream vs bounded_stream the way it is now in Falcon 2.0.
Despite that, I think your suggestion is great regarding our official testing client. I.e. stream would still break when using wsgiref and other servers requiring this normalization, but our testing client would not. I will create a follow-up proposal issue shortly.
Edit: @metazool I filed your suggestion under https://github.com/falconry/falcon/issues/1617
I also ran into this bug today. The broken test still shows on the "stable" version of the tutorial, although the fixed test is visible in "latest". Since this is essentially a bugfix, you might consider releasing the fix as 2.0.1. :-)
Most helpful comment
I've just come across this issue in a set of falcon tests which hadn't been run for quite a few months, where any reference to
streamorstream.read()in the application was raising the AssertionError.I can confirm that changing all references to
streamtobounded_streampassed the wsgiref validation.I wish i'd found this issue before the headscratching trial and error rather than after it ;)
As deployed in
gunicornthe application was working fine without the change, and it did feel like servicing the code to fit the tests. I would _really_ recommend revisiting the behaviour of thewsgirefvalidation in the falcon testing interface