[Python-modules-team] Bug#952172: django-oauth-toolkit: FTBFS: dh_auto_test: error: pybuild --test --test-pytest -i python{version} -p "3.8 3.7" --system=custom "--test-args=PYTHONPATH={build_dir} {interpreter} -m pytest" returned exit code 13

Lucas Nussbaum lucas at debian.org
Sun Feb 23 13:06:46 GMT 2020


Source: django-oauth-toolkit
Version: 1.2.0-2
Severity: serious
Justification: FTBFS on amd64
Tags: bullseye sid ftbfs
Usertags: ftbfs-20200222 ftbfs-bullseye

Hi,

During a rebuild of all packages in sid, your package failed to build
on amd64.

Relevant part (hopefully):
> make[1]: Entering directory '/<<PKGBUILDDIR>>'
> dh_auto_test -- --system=custom --test-args="PYTHONPATH={build_dir} {interpreter} -m pytest"
> I: pybuild base:217: PYTHONPATH=/<<PKGBUILDDIR>>/.pybuild/cpython3_3.8_django-oauth-toolkit/build python3.8 -m pytest
> ============================= test session starts ==============================
> platform linux -- Python 3.8.2rc2, pytest-4.6.9, py-1.8.1, pluggy-0.13.0
> Django settings: tests.settings (from ini file)
> rootdir: /<<PKGBUILDDIR>>, inifile: tox.ini
> plugins: django-3.5.1
> collected 221 items
> 
> tests/test_application_views.py .....                                    [  2%]
> tests/test_auth_backends.py ........                                     [  5%]
> tests/test_authorization_code.py .......................F..F......FFF..F [ 23%]
> ......                                                                   [ 26%]
> tests/test_client_credential.py .....                                    [ 28%]
> tests/test_decorators.py ...                                             [ 29%]
> tests/test_generator.py ...                                              [ 31%]
> tests/test_implicit.py ...........                                       [ 36%]
> tests/test_introspection_auth.py .....                                   [ 38%]
> tests/test_introspection_view.py .........                               [ 42%]
> tests/test_mixins.py ........                                            [ 46%]
> tests/test_models.py .......................                             [ 56%]
> tests/test_oauth2_backends.py ......                                     [ 59%]
> tests/test_oauth2_validators.py .........................                [ 70%]
> tests/test_password.py F..                                               [ 71%]
> tests/test_rest_framework.py .............................               [ 85%]
> tests/test_scopes.py ............                                        [ 90%]
> tests/test_scopes_backend.py ..                                          [ 91%]
> tests/test_token_revocation.py FFFFFF                                    [ 94%]
> tests/test_token_view.py ..........                                      [ 98%]
> tests/test_validators.py ...                                             [100%]
> 
> =================================== FAILURES ===================================
> _________ TestAuthorizationCodeTokenView.test_basic_auth_bad_authcode __________
> 
> self = <tests.test_authorization_code.TestAuthorizationCodeTokenView testMethod=test_basic_auth_bad_authcode>
> 
>     def test_basic_auth_bad_authcode(self):
>         """
>         Request an access token using a bad authorization code
>         """
>         self.client.login(username="test_user", password="123456")
>     
>         token_request_data = {
>             "grant_type": "authorization_code",
>             "code": "BLAH",
>             "redirect_uri": "http://example.org"
>         }
>         auth_headers = get_basic_auth_header(self.application.client_id, self.application.client_secret)
>     
>         response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
> >       self.assertEqual(response.status_code, 401)
> E       AssertionError: 400 != 401
> 
> tests/test_authorization_code.py:854: AssertionError
> _________ TestAuthorizationCodeTokenView.test_basic_auth_grant_expired _________
> 
> self = <tests.test_authorization_code.TestAuthorizationCodeTokenView testMethod=test_basic_auth_grant_expired>
> 
>     def test_basic_auth_grant_expired(self):
>         """
>         Request an access token using an expired grant token
>         """
>         self.client.login(username="test_user", password="123456")
>         g = Grant(
>             application=self.application, user=self.test_user, code="BLAH",
>             expires=timezone.now(), redirect_uri="", scope="")
>         g.save()
>     
>         token_request_data = {
>             "grant_type": "authorization_code",
>             "code": "BLAH",
>             "redirect_uri": "http://example.org"
>         }
>         auth_headers = get_basic_auth_header(self.application.client_id, self.application.client_secret)
>     
>         response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
> >       self.assertEqual(response.status_code, 401)
> E       AssertionError: 400 != 401
> 
> tests/test_authorization_code.py:890: AssertionError
> _________________ TestAuthorizationCodeTokenView.test_refresh __________________
> 
> self = <tests.test_authorization_code.TestAuthorizationCodeTokenView testMethod=test_refresh>
> 
>     def test_refresh(self):
>         """
>         Request an access token using a refresh token
>         """
>         self.client.login(username="test_user", password="123456")
>         authorization_code = self.get_auth()
>     
>         token_request_data = {
>             "grant_type": "authorization_code",
>             "code": authorization_code,
>             "redirect_uri": "http://example.org"
>         }
>         auth_headers = get_basic_auth_header(self.application.client_id, self.application.client_secret)
>     
>         response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
>         content = json.loads(response.content.decode("utf-8"))
>         self.assertTrue("refresh_token" in content)
>     
>         # make a second token request to be sure the previous refresh token remains valid, see #65
>         authorization_code = self.get_auth()
>         token_request_data = {
>             "grant_type": "authorization_code",
>             "code": authorization_code,
>             "redirect_uri": "http://example.org"
>         }
>         response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
>     
>         token_request_data = {
>             "grant_type": "refresh_token",
>             "refresh_token": content["refresh_token"],
>             "scope": content["scope"],
>         }
>         response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
>         self.assertEqual(response.status_code, 200)
>     
>         content = json.loads(response.content.decode("utf-8"))
>         self.assertTrue("access_token" in content)
>     
>         # check refresh token cannot be used twice
>         response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
> >       self.assertEqual(response.status_code, 401)
> E       AssertionError: 400 != 401
> 
> tests/test_authorization_code.py:602: AssertionError
> ------------------------------ Captured log call -------------------------------
> DEBUG    oauth2_provider:base.py:123 Success url for the request: http://example.org?code=l2AmHuE4wbSp2reQQN45z16cP3J0PO&state=random_state_string
> DEBUG    oauth2_provider:base.py:123 Success url for the request: http://example.org?code=cRHhTdtbcuflkVoOTyPZyz6PbBekAL&state=random_state_string
> ____________ TestAuthorizationCodeTokenView.test_refresh_bad_scopes ____________
> 
> self = <tests.test_authorization_code.TestAuthorizationCodeTokenView testMethod=test_refresh_bad_scopes>
> 
>     def test_refresh_bad_scopes(self):
>         """
>         Request an access token using a refresh token and wrong scopes
>         """
>         self.client.login(username="test_user", password="123456")
>         authorization_code = self.get_auth()
>     
>         token_request_data = {
>             "grant_type": "authorization_code",
>             "code": authorization_code,
>             "redirect_uri": "http://example.org"
>         }
>         auth_headers = get_basic_auth_header(self.application.client_id, self.application.client_secret)
>     
>         response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
>         content = json.loads(response.content.decode("utf-8"))
>         self.assertTrue("refresh_token" in content)
>     
>         token_request_data = {
>             "grant_type": "refresh_token",
>             "refresh_token": content["refresh_token"],
>             "scope": "read write nuke",
>         }
>         response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
> >       self.assertEqual(response.status_code, 401)
> E       AssertionError: 400 != 401
> 
> tests/test_authorization_code.py:738: AssertionError
> ------------------------------ Captured log call -------------------------------
> DEBUG    oauth2_provider:base.py:123 Success url for the request: http://example.org?code=iJ1ZqhQpW7nGz72LgOCtZtAMc1AMkT&state=random_state_string
> _____ TestAuthorizationCodeTokenView.test_refresh_fail_repeating_requests ______
> 
> self = <tests.test_authorization_code.TestAuthorizationCodeTokenView testMethod=test_refresh_fail_repeating_requests>
> 
>     def test_refresh_fail_repeating_requests(self):
>         """
>         Try refreshing an access token with the same refresh token more than once
>         """
>         self.client.login(username="test_user", password="123456")
>         authorization_code = self.get_auth()
>     
>         token_request_data = {
>             "grant_type": "authorization_code",
>             "code": authorization_code,
>             "redirect_uri": "http://example.org"
>         }
>         auth_headers = get_basic_auth_header(self.application.client_id, self.application.client_secret)
>     
>         response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
>         content = json.loads(response.content.decode("utf-8"))
>         self.assertTrue("refresh_token" in content)
>     
>         token_request_data = {
>             "grant_type": "refresh_token",
>             "refresh_token": content["refresh_token"],
>             "scope": content["scope"],
>         }
>         response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
>         self.assertEqual(response.status_code, 200)
>         response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
> >       self.assertEqual(response.status_code, 401)
> E       AssertionError: 400 != 401
> 
> tests/test_authorization_code.py:766: AssertionError
> ------------------------------ Captured log call -------------------------------
> DEBUG    oauth2_provider:base.py:123 Success url for the request: http://example.org?code=6b3Ykx9JcNqfZZP34hXp4LQKEMbfkf&state=random_state_string
> ________ TestAuthorizationCodeTokenView.test_refresh_repeating_requests ________
> 
> self = <tests.test_authorization_code.TestAuthorizationCodeTokenView testMethod=test_refresh_repeating_requests>
> 
>     def test_refresh_repeating_requests(self):
>         """
>         Trying to refresh an access token with the same refresh token more than
>         once succeeds in the grace period and fails outside
>         """
>         oauth2_settings.REFRESH_TOKEN_GRACE_PERIOD_SECONDS = 120
>         self.client.login(username="test_user", password="123456")
>         authorization_code = self.get_auth()
>     
>         token_request_data = {
>             "grant_type": "authorization_code",
>             "code": authorization_code,
>             "redirect_uri": "http://example.org"
>         }
>         auth_headers = get_basic_auth_header(self.application.client_id, self.application.client_secret)
>     
>         response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
>         content = json.loads(response.content.decode("utf-8"))
>         self.assertTrue("refresh_token" in content)
>     
>         token_request_data = {
>             "grant_type": "refresh_token",
>             "refresh_token": content["refresh_token"],
>             "scope": content["scope"],
>         }
>         response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
>         self.assertEqual(response.status_code, 200)
>         response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
>         self.assertEqual(response.status_code, 200)
>     
>         # try refreshing outside the refresh window, see #497
>         rt = RefreshToken.objects.get(token=content["refresh_token"])
>         self.assertIsNotNone(rt.revoked)
>         rt.revoked = timezone.now() - datetime.timedelta(minutes=10)  # instead of mocking out datetime
>         rt.save()
>     
>         response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
> >       self.assertEqual(response.status_code, 401)
> E       AssertionError: 400 != 401
> 
> tests/test_authorization_code.py:805: AssertionError
> ------------------------------ Captured log call -------------------------------
> DEBUG    oauth2_provider:base.py:123 Success url for the request: http://example.org?code=6Op5KhS2YPELG4NWKYkhIL2OJb8Y3G&state=random_state_string
> __________________ TestPasswordTokenView.test_bad_credentials __________________
> 
> self = <tests.test_password.TestPasswordTokenView testMethod=test_bad_credentials>
> 
>     def test_bad_credentials(self):
>         """
>         Request an access token using Resource Owner Password Flow
>         """
>         token_request_data = {
>             "grant_type": "password",
>             "username": "test_user",
>             "password": "NOT_MY_PASS",
>         }
>         auth_headers = get_basic_auth_header(self.application.client_id, self.application.client_secret)
>     
>         response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
> >       self.assertEqual(response.status_code, 401)
> E       AssertionError: 400 != 401
> 
> tests/test_password.py:79: AssertionError
> _________________ TestRevocationView.test_revoke_access_token __________________
> 
> self = <tests.test_token_revocation.TestRevocationView testMethod=test_revoke_access_token>
> 
>     def test_revoke_access_token(self):
>         """
>     
>         """
>         tok = AccessToken.objects.create(
>             user=self.test_user, token="1234567890",
>             application=self.application,
>             expires=timezone.now() + datetime.timedelta(days=1),
>             scope="read write"
>         )
>         query_string = urlencode({
>             "client_id": self.application.client_id,
>             "client_secret": self.application.client_secret,
>             "token": tok.token,
>         })
>         url = "{url}?{qs}".format(url=reverse("oauth2_provider:revoke-token"), qs=query_string)
>         response = self.client.post(url)
> >       self.assertEqual(response.status_code, 200)
> E       AssertionError: 400 != 200
> 
> tests/test_token_revocation.py:62: AssertionError
> ______________ TestRevocationView.test_revoke_access_token_public ______________
> 
> self = <tests.test_token_revocation.TestRevocationView testMethod=test_revoke_access_token_public>
> 
>     def test_revoke_access_token_public(self):
>         public_app = Application(
>             name="Test Application",
>             redirect_uris="http://localhost http://example.com http://example.org",
>             user=self.dev_user,
>             client_type=Application.CLIENT_PUBLIC,
>             authorization_grant_type=Application.GRANT_AUTHORIZATION_CODE,
>         )
>         public_app.save()
>     
>         tok = AccessToken.objects.create(
>             user=self.test_user, token="1234567890", application=public_app,
>             expires=timezone.now() + datetime.timedelta(days=1),
>             scope="read write"
>         )
>     
>         query_string = urlencode({
>             "client_id": public_app.client_id,
>             "token": tok.token,
>         })
>     
>         url = "{url}?{qs}".format(url=reverse("oauth2_provider:revoke-token"), qs=query_string)
>         response = self.client.post(url)
> >       self.assertEqual(response.status_code, 200)
> E       AssertionError: 400 != 200
> 
> tests/test_token_revocation.py:89: AssertionError
> ____________ TestRevocationView.test_revoke_access_token_with_hint _____________
> 
> self = <tests.test_token_revocation.TestRevocationView testMethod=test_revoke_access_token_with_hint>
> 
>     def test_revoke_access_token_with_hint(self):
>         """
>     
>         """
>         tok = AccessToken.objects.create(
>             user=self.test_user, token="1234567890",
>             application=self.application,
>             expires=timezone.now() + datetime.timedelta(days=1),
>             scope="read write"
>         )
>         query_string = urlencode({
>             "client_id": self.application.client_id,
>             "client_secret": self.application.client_secret,
>             "token": tok.token,
>             "token_type_hint": "access_token"
>         })
>         url = "{url}?{qs}".format(url=reverse("oauth2_provider:revoke-token"), qs=query_string)
>         response = self.client.post(url)
> >       self.assertEqual(response.status_code, 200)
> E       AssertionError: 400 != 200
> 
> tests/test_token_revocation.py:109: AssertionError
> ________ TestRevocationView.test_revoke_access_token_with_invalid_hint _________
> 
> self = <tests.test_token_revocation.TestRevocationView testMethod=test_revoke_access_token_with_invalid_hint>
> 
>     def test_revoke_access_token_with_invalid_hint(self):
>         tok = AccessToken.objects.create(
>             user=self.test_user, token="1234567890",
>             application=self.application,
>             expires=timezone.now() + datetime.timedelta(days=1),
>             scope="read write"
>         )
>         # invalid hint should have no effect
>         query_string = urlencode({
>             "client_id": self.application.client_id,
>             "client_secret": self.application.client_secret,
>             "token": tok.token,
>             "token_type_hint": "bad_hint"
>         })
>         url = "{url}?{qs}".format(url=reverse("oauth2_provider:revoke-token"), qs=query_string)
>         response = self.client.post(url)
> >       self.assertEqual(response.status_code, 200)
> E       AssertionError: 400 != 200
> 
> tests/test_token_revocation.py:128: AssertionError
> _________________ TestRevocationView.test_revoke_refresh_token _________________
> 
> self = <tests.test_token_revocation.TestRevocationView testMethod=test_revoke_refresh_token>
> 
>     def test_revoke_refresh_token(self):
>         tok = AccessToken.objects.create(
>             user=self.test_user, token="1234567890",
>             application=self.application,
>             expires=timezone.now() + datetime.timedelta(days=1),
>             scope="read write"
>         )
>         rtok = RefreshToken.objects.create(
>             user=self.test_user, token="999999999",
>             application=self.application, access_token=tok
>         )
>         query_string = urlencode({
>             "client_id": self.application.client_id,
>             "client_secret": self.application.client_secret,
>             "token": rtok.token,
>         })
>         url = "{url}?{qs}".format(url=reverse("oauth2_provider:revoke-token"), qs=query_string)
>         response = self.client.post(url)
> >       self.assertEqual(response.status_code, 200)
> E       AssertionError: 400 != 200
> 
> tests/test_token_revocation.py:149: AssertionError
> _____________ TestRevocationView.test_revoke_token_with_wrong_hint _____________
> 
> self = <tests.test_token_revocation.TestRevocationView testMethod=test_revoke_token_with_wrong_hint>
> 
>     def test_revoke_token_with_wrong_hint(self):
>         """
>         From the revocation rfc, `Section 4.1.2`_ :
>     
>         If the server is unable to locate the token using the given hint,
>         it MUST extend its search across all of its supported token types
>         .. _`Section 4.1.2`: http://tools.ietf.org/html/draft-ietf-oauth-revocation-11#section-4.1.2
>         """
>         tok = AccessToken.objects.create(
>             user=self.test_user, token="1234567890",
>             application=self.application,
>             expires=timezone.now() + datetime.timedelta(days=1),
>             scope="read write"
>         )
>     
>         query_string = urlencode({
>             "client_id": self.application.client_id,
>             "client_secret": self.application.client_secret,
>             "token": tok.token,
>             "token_type_hint": "refresh_token"
>         })
>         url = "{url}?{qs}".format(url=reverse("oauth2_provider:revoke-token"), qs=query_string)
>         response = self.client.post(url)
> >       self.assertEqual(response.status_code, 200)
> E       AssertionError: 400 != 200
> 
> tests/test_token_revocation.py:177: AssertionError
> =============================== warnings summary ===============================
> tests/test_application_views.py::TestApplicationViews::test_application_detail_owner
> tests/test_application_views.py::TestApplicationViews::test_application_list
> tests/test_authorization_code.py::TestRegressionIssue315::test_request_is_not_overwritten
> tests/test_authorization_code.py::TestAuthorizationCodeView::test_code_post_auth_fails_when_redirect_uri_path_is_invalid
> tests/test_authorization_code.py::TestAuthorizationCodeView::test_code_post_auth_forbidden_redirect_uri
> tests/test_authorization_code.py::TestAuthorizationCodeView::test_code_post_auth_malicious_redirect_uri
> tests/test_authorization_code.py::TestAuthorizationCodeView::test_pre_auth_approval_prompt
> tests/test_authorization_code.py::TestAuthorizationCodeView::test_pre_auth_approval_prompt_default
> tests/test_authorization_code.py::TestAuthorizationCodeView::test_pre_auth_default_redirect
> tests/test_authorization_code.py::TestAuthorizationCodeView::test_pre_auth_forbibben_redirect
> tests/test_authorization_code.py::TestAuthorizationCodeView::test_pre_auth_invalid_client
> tests/test_authorization_code.py::TestAuthorizationCodeView::test_pre_auth_valid_client
> tests/test_authorization_code.py::TestAuthorizationCodeView::test_pre_auth_valid_client_custom_redirect_uri_scheme
> tests/test_authorization_code.py::TestDefaultScopes::test_pre_auth_default_scopes
> tests/test_implicit.py::TestImplicitAuthorizationCodeView::test_implicit_fails_when_redirect_uri_path_is_invalid
> tests/test_implicit.py::TestImplicitAuthorizationCodeView::test_pre_auth_default_redirect
> tests/test_implicit.py::TestImplicitAuthorizationCodeView::test_pre_auth_forbibben_redirect
> tests/test_implicit.py::TestImplicitAuthorizationCodeView::test_pre_auth_invalid_client
> tests/test_implicit.py::TestImplicitAuthorizationCodeView::test_pre_auth_valid_client
> tests/test_implicit.py::TestImplicitAuthorizationCodeView::test_pre_auth_valid_client_default_scopes
> tests/test_token_view.py::TestAuthorizedTokenListView::test_empty_list_view
> tests/test_token_view.py::TestAuthorizedTokenListView::test_list_view_one_token
> tests/test_token_view.py::TestAuthorizedTokenListView::test_list_view_shows_correct_user_token
> tests/test_token_view.py::TestAuthorizedTokenListView::test_list_view_two_tokens
> tests/test_token_view.py::TestAuthorizedTokenDeleteView::test_delete_view_post_actually_deletes
> tests/test_token_view.py::TestAuthorizedTokenDeleteView::test_delete_view_works
>   /usr/lib/python3/dist-packages/django/contrib/staticfiles/templatetags/staticfiles.py:24: RemovedInDjango30Warning: {% load staticfiles %} is deprecated in favor of {% load static %}.
>     warnings.warn(
> 
> -- Docs: https://docs.pytest.org/en/latest/warnings.html
> ============= 13 failed, 208 passed, 26 warnings in 40.01 seconds ==============
> E: pybuild pybuild:341: test: plugin custom failed with: exit code=1: PYTHONPATH=/<<PKGBUILDDIR>>/.pybuild/cpython3_3.8_django-oauth-toolkit/build python3.8 -m pytest
> dh_auto_test: error: pybuild --test --test-pytest -i python{version} -p "3.8 3.7" --system=custom "--test-args=PYTHONPATH={build_dir} {interpreter} -m pytest" returned exit code 13

The full build log is available from:
   http://qa-logs.debian.net/2020/02/22/django-oauth-toolkit_1.2.0-2_unstable.log

A list of current common problems and possible solutions is available at
http://wiki.debian.org/qa.debian.org/FTBFS . You're welcome to contribute!

About the archive rebuild: The rebuild was done on EC2 VM instances from
Amazon Web Services, using a clean, minimal and up-to-date chroot. Every
failed build was retried once to eliminate random failures.



More information about the Python-modules-team mailing list