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:
7
scripts/get-test-instance-id.sh
Executable file
7
scripts/get-test-instance-id.sh
Executable 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
|
||||||
39
scripts/run-integration-tests.sh
Executable file
39
scripts/run-integration-tests.sh
Executable 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
|
||||||
@@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user