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

Tests are failing with the latest werkzeug 2.0.1 #647

Open
frenzymadness opened this issue Jun 23, 2021 · 6 comments
Open

Tests are failing with the latest werkzeug 2.0.1 #647

frenzymadness opened this issue Jun 23, 2021 · 6 comments
Labels

Comments

@frenzymadness
Copy link

/usr/bin/python3 test_httpbin.py
....................................FFFFF......................
======================================================================
FAIL: test_redirect_n_equals_to_1 (__main__.HttpbinTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/httpbin-0.7.0/test_httpbin.py", line 549, in test_redirect_n_equals_to_1
    self.assertEqual(
AssertionError: 'http://localhost/get' != '/get'
- http://localhost/get
+ /get


======================================================================
FAIL: test_redirect_n_higher_than_1 (__main__.HttpbinTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/httpbin-0.7.0/test_httpbin.py", line 527, in test_redirect_n_higher_than_1
    self.assertEqual(
AssertionError: 'http://localhost/relative-redirect/4' != '/relative-redirect/4'
- http://localhost/relative-redirect/4
+ /relative-redirect/4


======================================================================
FAIL: test_redirect_to_post (__main__.HttpbinTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/httpbin-0.7.0/test_httpbin.py", line 536, in test_redirect_to_post
    self.assertEqual(
AssertionError: 'http://localhost/post' != '/post'
- http://localhost/post
+ /post


======================================================================
FAIL: test_relative_redirect_n_equals_to_1 (__main__.HttpbinTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/httpbin-0.7.0/test_httpbin.py", line 555, in test_relative_redirect_n_equals_to_1
    self.assertEqual(
AssertionError: 'http://localhost/get' != '/get'
- http://localhost/get
+ /get


======================================================================
FAIL: test_relative_redirect_n_higher_than_1 (__main__.HttpbinTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/httpbin-0.7.0/test_httpbin.py", line 562, in test_relative_redirect_n_higher_than_1
    self.assertEqual(
AssertionError: 'http://localhost/relative-redirect/6' != '/relative-redirect/6'
- http://localhost/relative-redirect/6
+ /relative-redirect/6


----------------------------------------------------------------------
Ran 63 tests in 6.087s

FAILED (failures=5)
@frenzymadness frenzymadness changed the title Tests are faiing with the latest werkzeug 2.0.1 Tests are failing with the latest werkzeug 2.0.1 Jun 24, 2021
@AdamWill
Copy link
Contributor

sorry, previous comment was wrong. This is caused by a change in werkzeug. I bisected it, and the problematic commit I think is pallets/werkzeug@2cd4fa9 - this was a little hard to debug because there's a commit in the history that seems to break werkzeug entirely with Python 3.10 at least, I had to use an 'alternative history' branch where I fixed the bug in that commit to do a successful bisect.

As best I can tell, something somewhere in there is messing with responses before they're returned. for e.g. the failure in test_redirect_to_post - that test is backed by redirect_to in httpbin/core.py. If I log what the "Location" header in the response is right before redirect_to returns, it's correct - it's just /post. So something else between that function returning and the response actually getting back to test_redirect_to_post is messing with the response and making the "Location" absolute.

@AdamWill
Copy link
Contributor

@davidism ahoy! Hope you don't mind the ping. Any idea what's going on here, as you wrote the commit that seems to have caused it? It's a big commit and I'm struggling to pinpoint the issue. The stuff about autocorrect_location_header obviously looks like a suspect, but I can't see that that code actually changed in the commit, so much as just moved...

@davidism
Copy link

As far as I understand it, autocorrect_location_header has always produced full URLs, not just paths. If you don't want that behavior, you can set Response.autocorrect_location_header = False, but I'm not sure what exactly that implies. I'm not sure why the tests were seeing path-only URLs before.

To debug this, I'd set a breakpoint in the if self.autocorrect_location_header block and see what it's doing differently in 1.x and 2.x.

@AdamWill
Copy link
Contributor

AdamWill commented Jul 16, 2021

yeah, I'm not saying that part actually is the problem, it's just the most obvious thing I saw on a brief look through the commit.

Most of the tests are of httpbin code that very explicitly intends to get relative URLs. redirect_to doesn't, in particular, but relative_redirect_n_times for instance has a bit of an obvious clue in the name, and does this:

response.headers["Location"] = url_for("relative_redirect_n_times", n=n - 1, _external=False)

where using _external=False is specifically ensuring it gets a relative path, not an absolute one. So httpbin is definitely specifically trying to get/return relative Locations in several of the tests, and previously was getting them, but after that commit it is ultimately producing absolute ones.

Your suggested next step was probably what I was gonna do next too, but I figured instead of flailing around blindly at "likely suspects" it'd be an idea to see if the person who wrote it could spot the issue :)

@AdamWill
Copy link
Contributor

AdamWill commented Jul 19, 2021

OK, so I added some debug prints and indeed the issue is autocorrect_location_header, somehow (I still don't have the how figured out). Before 2cd4fa9 , somehow, we do not enter the if self.autocorrect_location_header: block during the affected tests. After 2cd4fa9 , we do enter that block. Trying to figure out why now.

@AdamWill
Copy link
Contributor

Ah. Heh. Turns out it's really pretty simple, and I dunno why I didn't notice it before...httpbin's core.py has this:

# Prevent WSGI from correcting the casing of the Location header
BaseResponse.autocorrect_location_header = False

which obviously stopped 'working' when the logic moved to Response. That should be fairly easy to fix.

AdamWill added a commit to AdamWill/httpbin that referenced this issue Jul 19, 2021
…labs#647)

In werkzeug 2.0.0 and later, the Location header autocorrection
moved from BaseResponse to Response, so we need to set
`autocorrect_location_header = False` in `Response` not
`BaseResponse`. For now let's just set it in both to be safe,
this doesn't cause any errors at least with 1.0.1 and 2.0.1.

Signed-off-by: Adam Williamson <awilliam@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants