graphql-python / graphene

GraphQL framework for Python
http://graphene-python.org/
MIT License
8.1k stars 827 forks source link

Schema execution timing out after upgrade from 2.1.9 to 3.3 #1573

Closed xeon826 closed 4 months ago

xeon826 commented 4 months ago

I was using version 2.1.9. I'm now using version 3.3. This code has not been changed since the upgrade, I'm going to outline the relevant code and then explain the problem further

build_schema: neither Query or Mutation are None so this will return graphene.Schema(query=Query, mutation=Mutation)

@logf(level='debug')
def build_schema(*args, **kwargs) -> graphene.Schema:
    """Builds the Query and Mutation classes for the given
    schema name and adds them a schema and returns the schema
    """
    Query, Mutation = None, None
    qclasses, qprops = _build_props('queries', *args, **kwargs)
    if qclasses:
        Query = type('Query', qclasses, qprops)

    mclasses, mprops = _build_props('mutations', *args, **kwargs)
    if mclasses:
        Mutation = type('Mutation', mclasses, mprops)

    if Query is None and Mutation is None:
        raise ValueError('No Query or Mutation classes found')
    elif Query is None:
        gqlschema = graphene.Schema(mutation=Mutation)
    elif Mutation is None:
        gqlschema = graphene.Schema(query=Query)
    else:
        gqlschema = graphene.Schema(query=Query, mutation=Mutation)

    return gqlschema

This is the test case that fails, it's not verbose about why it failed, it just hangs for 60 seconds and then says that it timed out

def _mock_user(user='test', **kwargs):
    return MagicMock(username=user, **kwargs)

def _mock_info(**kwargs):
    infomock = MagicMock()
    infomock.context.user = _mock_user(**kwargs)
    return infomock

class TestSignUrlQuery(TestCase):
    def setUp(self):
        self.query = '''
            query {
                signedUrl(
                    gcsUrl: "bucket/path/to/file",
                    method: "PUT",
                    contentType: "image/png",
                    acl: "project-private",
                    expires: 60
                )
            }
        '''
        self.schema = build_schema()

    @patch('pict_api.graphqlapi.internal.gcloud.queries.isAuthorized')
    @patch('pict_api.graphqlapi.internal.gcloud.queries.generate_signed_url')
    def test_signed_url_query(self, mock_gen_url, mock_is_auth):
        mock_gen_url.return_value = 'https://signed.url'
        infomock = _mock_info()
        print('schema', self.schema)
        result = self.schema.execute(
            self.query,
            context_value=infomock.context  # Updated to context_value
        )
        self.assertFalse(result.errors)
        self.assertEqual(result.data['signedUrl'], 'https://signed.url')
        self.assertTrue(mock_is_auth.called)
        self.assertTrue(mock_is_auth.called_with(infomock, [POD_ACCESS]))
        self.assertTrue(mock_gen_url.called)
        mock_gen_url.assert_called_with(
            'bucket/path/to/file',
            method='PUT',
            expiration=60,
            content_type='image/png',
            acl='project-private',
        )

    @patch(
        'pict_api.graphqlapi.internal.gcloud.queries.isAuthorized',
        side_effect=GraphQLError('Not Authorized'),
    )
    @patch('pict_api.graphqlapi.internal.gcloud.queries.generate_signed_url')
    def test_signed_url_badauth(self, mock_gen_url, mock_is_auth):
        mock_is_auth.return_value = None
        infomock = _mock_info(user=None)

        result = self.schema.execute(
            self.query,
            context_value=infomock.context  # Updated to context_value
        )
        self.assertEqual(len(result.errors), 1)
        self.assertFalse(mock_gen_url.called)

I've verified that the signedUrl query is present in the schema and that the arguments match the required type, I also tried using context instead of context_value, I'm sure it's to do with the upgrade from 2.1.9 to 3.3 though I'm not sure what in particular I should change. I also tried converting the test into an asynchronous function and using execute_async but I still get the same result. In addition, I tried using check_sync=True to no avail.

To reiterate: the test is hanging on this statement

result = self.schema.execute(
    self.query,
    context_value=infomock.context  # Updated to context_value
)

And it is not verbose about why, only that it times out after 60 seconds. What am I doing wrong?