From e934f0d0c2414ff82522baa8f9d25931b99d2a8e Mon Sep 17 00:00:00 2001 From: Zamil Majdy Date: Tue, 10 Feb 2026 20:17:07 +0400 Subject: [PATCH] fix(tests): Remove session-scoped fixture overrides from MCP conftest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The MCP conftest.py was overriding session-scoped `server` and `graph_cleanup` fixtures with no-op versions. Having two session-scoped fixtures with the same name at different directory levels caused pytest-asyncio event loop conflicts, making all oauth_test.py tests fail with "Event loop is closed". Since these fixtures are session-scoped and shared across the entire test run, the override was unnecessary — the SpinTestServer is already created for other tests. Also adds defensive `access_token` key validation in MCP OAuth token exchange and refresh to prevent KeyError on malformed responses. --- .../backend/backend/blocks/mcp/conftest.py | 18 ++---------------- .../backend/backend/blocks/mcp/oauth.py | 10 ++++++++++ 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/autogpt_platform/backend/backend/blocks/mcp/conftest.py b/autogpt_platform/backend/backend/blocks/mcp/conftest.py index d944a731c8..ee984832ff 100644 --- a/autogpt_platform/backend/backend/blocks/mcp/conftest.py +++ b/autogpt_platform/backend/backend/blocks/mcp/conftest.py @@ -1,13 +1,11 @@ """ Conftest for MCP block tests. -Override the session-scoped server and graph_cleanup fixtures from -backend/conftest.py so that MCP integration tests don't spin up the -full SpinTestServer infrastructure. +Registers the e2e marker and --run-e2e CLI option so MCP end-to-end tests +(which hit real external servers) can be gated behind a flag. """ import pytest -import pytest_asyncio def pytest_configure(config: pytest.Config) -> None: @@ -29,15 +27,3 @@ def pytest_addoption(parser: pytest.Parser) -> None: parser.addoption( "--run-e2e", action="store_true", default=False, help="run e2e tests" ) - - -@pytest_asyncio.fixture(scope="session", loop_scope="session") -async def server(): - """No-op override — MCP tests don't need the full platform server.""" - yield None - - -@pytest_asyncio.fixture(scope="session", loop_scope="session", autouse=True) -async def graph_cleanup(server): - """No-op override — MCP tests don't create graphs.""" - yield diff --git a/autogpt_platform/backend/backend/blocks/mcp/oauth.py b/autogpt_platform/backend/backend/blocks/mcp/oauth.py index 0849540300..f49444b4a7 100644 --- a/autogpt_platform/backend/backend/blocks/mcp/oauth.py +++ b/autogpt_platform/backend/backend/blocks/mcp/oauth.py @@ -109,6 +109,11 @@ class MCPOAuthHandler(BaseOAuthHandler): f"Token exchange failed: {tokens.get('error_description', tokens['error'])}" ) + if "access_token" not in tokens: + raise RuntimeError( + "OAuth token response missing 'access_token' field" + ) + now = int(time.time()) expires_in = tokens.get("expires_in") @@ -158,6 +163,11 @@ class MCPOAuthHandler(BaseOAuthHandler): f"Token refresh failed: {tokens.get('error_description', tokens['error'])}" ) + if "access_token" not in tokens: + raise RuntimeError( + "OAuth refresh response missing 'access_token' field" + ) + now = int(time.time()) expires_in = tokens.get("expires_in")