feat: add test isolation scripts with dynamic port discovery

- Add get-test-instance-id.sh for branch-based container isolation
- Add run-integration-tests.sh for full test lifecycle management
- Update integration tests to read service URLs from environment
  variables (GRIST_MCP_URL, MOCK_GRIST_URL) with fallback defaults
This commit is contained in:
2025-12-30 19:11:04 -05:00
parent 757afb3c41
commit f921412f01
5 changed files with 54 additions and 5 deletions

View File

@@ -0,0 +1,7 @@
#!/bin/bash
# scripts/get-test-instance-id.sh
# Generate a unique instance ID from git branch for parallel test isolation
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
# Sanitize: replace non-alphanumeric with dash, limit length
echo "$BRANCH" | sed 's/[^a-zA-Z0-9]/-/g' | cut -c1-20

View File

@@ -0,0 +1,39 @@
#!/bin/bash
# scripts/run-integration-tests.sh
# Run integration tests with branch isolation and dynamic port discovery
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
# Get branch-based instance ID
TEST_INSTANCE_ID=$("$SCRIPT_DIR/get-test-instance-id.sh")
export TEST_INSTANCE_ID
echo "Test instance ID: $TEST_INSTANCE_ID"
# Start containers
cd "$PROJECT_ROOT/deploy/test"
docker compose up -d --build --wait
# Discover dynamic ports
GRIST_MCP_PORT=$(docker compose port grist-mcp 3000 | cut -d: -f2)
MOCK_GRIST_PORT=$(docker compose port mock-grist 8484 | cut -d: -f2)
echo "grist-mcp available at: http://localhost:$GRIST_MCP_PORT"
echo "mock-grist available at: http://localhost:$MOCK_GRIST_PORT"
# Export for tests
export GRIST_MCP_URL="http://localhost:$GRIST_MCP_PORT"
export MOCK_GRIST_URL="http://localhost:$MOCK_GRIST_PORT"
# Run tests
cd "$PROJECT_ROOT"
TEST_EXIT=0
uv run pytest tests/integration/ -v || TEST_EXIT=$?
# Cleanup
cd "$PROJECT_ROOT/deploy/test"
docker compose down -v
exit $TEST_EXIT

View File

@@ -1,13 +1,14 @@
"""Fixtures for integration tests.""" """Fixtures for integration tests."""
import os
import time import time
import httpx import httpx
import pytest import pytest
GRIST_MCP_URL = "http://localhost:3000" GRIST_MCP_URL = os.environ.get("GRIST_MCP_URL", "http://localhost:3000")
MOCK_GRIST_URL = "http://localhost:8484" MOCK_GRIST_URL = os.environ.get("MOCK_GRIST_URL", "http://localhost:8484")
MAX_WAIT_SECONDS = 30 MAX_WAIT_SECONDS = 30

View File

@@ -1,5 +1,6 @@
"""Test MCP protocol compliance over SSE transport.""" """Test MCP protocol compliance over SSE transport."""
import os
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
import pytest import pytest
@@ -7,7 +8,7 @@ from mcp import ClientSession
from mcp.client.sse import sse_client from mcp.client.sse import sse_client
GRIST_MCP_URL = "http://localhost:3000" GRIST_MCP_URL = os.environ.get("GRIST_MCP_URL", "http://localhost:3000")
@asynccontextmanager @asynccontextmanager

View File

@@ -1,6 +1,7 @@
"""Test tool calls through MCP client to verify Grist API interactions.""" """Test tool calls through MCP client to verify Grist API interactions."""
import json import json
import os
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
import httpx import httpx
@@ -9,8 +10,8 @@ from mcp import ClientSession
from mcp.client.sse import sse_client from mcp.client.sse import sse_client
GRIST_MCP_URL = "http://localhost:3000" GRIST_MCP_URL = os.environ.get("GRIST_MCP_URL", "http://localhost:3000")
MOCK_GRIST_URL = "http://localhost:8484" MOCK_GRIST_URL = os.environ.get("MOCK_GRIST_URL", "http://localhost:8484")
@asynccontextmanager @asynccontextmanager