Comprehensive Tests #32
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Comprehensive Tests | |
| on: | |
| push: | |
| branches: [ main, develop ] | |
| pull_request: | |
| branches: [ main, develop ] | |
| schedule: | |
| # Run daily at 2 AM UTC to catch API changes | |
| - cron: '0 2 * * *' | |
| env: | |
| PYTHON_VERSION_DEFAULT: "3.12" | |
| jobs: | |
| # Quick smoke test - runs first to fail fast | |
| smoke-test: | |
| name: Smoke Test | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION_DEFAULT }} | |
| - name: Install minimal dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e . | |
| - name: Run smoke test | |
| run: | | |
| python smoke_test.py | |
| env: | |
| POLYGON_PRIVATE_KEY: "0000000000000000000000000000000000000000000000000000000000000001" | |
| POLYGON_ADDRESS: "0x0000000000000000000000000000000000000001" | |
| # Code quality checks | |
| lint: | |
| name: Lint & Format | |
| runs-on: ubuntu-latest | |
| needs: smoke-test | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION_DEFAULT }} | |
| - name: Cache pip packages | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.cache/pip | |
| key: ${{ runner.os }}-pip-lint-${{ hashFiles('**/pyproject.toml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pip-lint- | |
| ${{ runner.os }}-pip- | |
| - name: Install linting dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install ruff black mypy bandit safety | |
| - name: Lint with ruff | |
| run: | | |
| ruff check src/ tests/ --output-format=github | |
| - name: Format check with black | |
| run: | | |
| black --check src/ tests/ | |
| - name: Type check with mypy | |
| continue-on-error: true | |
| run: | | |
| mypy src/ --ignore-missing-imports --show-error-codes | |
| - name: Security check with bandit | |
| run: | | |
| bandit -r src/ -f json -o bandit-report.json || true | |
| bandit -r src/ -ll | |
| - name: Check dependency vulnerabilities | |
| run: | | |
| safety check --json || true | |
| safety check | |
| - name: Upload security reports | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: security-reports | |
| path: | | |
| bandit-report.json | |
| # Unit and functional tests with matrix | |
| test: | |
| name: Test (Python ${{ matrix.python-version }} on ${{ matrix.os }}) | |
| runs-on: ${{ matrix.os }} | |
| needs: smoke-test | |
| timeout-minutes: 15 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| python-version: ["3.10", "3.11", "3.12"] | |
| exclude: | |
| # Reduce matrix size - skip some combinations | |
| - os: macos-latest | |
| python-version: "3.10" | |
| - os: windows-latest | |
| python-version: "3.10" | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Cache pip packages | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cache/pip | |
| ~/Library/Caches/pip | |
| ~\AppData\Local\pip\Cache | |
| key: ${{ runner.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('**/pyproject.toml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pip-${{ matrix.python-version }}- | |
| ${{ runner.os }}-pip- | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[dev]" | |
| pip install pytest-xdist pytest-timeout | |
| - name: Run unit tests (parallel) | |
| run: | | |
| pytest tests/ -v -m "not integration and not slow and not real_api" \ | |
| --tb=short \ | |
| --maxfail=5 \ | |
| --timeout=60 \ | |
| -n auto | |
| env: | |
| POLYGON_PRIVATE_KEY: "0000000000000000000000000000000000000000000000000000000000000001" | |
| POLYGON_ADDRESS: "0x0000000000000000000000000000000000000001" | |
| POLYMARKET_CHAIN_ID: "137" | |
| - name: Run demo mode tests | |
| run: | | |
| pytest tests/ -v -m "not real_api" \ | |
| --tb=short \ | |
| --maxfail=3 | |
| env: | |
| POLYGON_PRIVATE_KEY: "0000000000000000000000000000000000000000000000000000000000000001" | |
| POLYGON_ADDRESS: "0x0000000000000000000000000000000000000001" | |
| POLYMARKET_DEMO_MODE: "true" | |
| # Coverage testing (only on Ubuntu with latest Python) | |
| coverage: | |
| name: Code Coverage | |
| runs-on: ubuntu-latest | |
| needs: smoke-test | |
| timeout-minutes: 20 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION_DEFAULT }} | |
| - name: Cache pip packages | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.cache/pip | |
| key: ${{ runner.os }}-pip-coverage-${{ hashFiles('**/pyproject.toml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pip-coverage- | |
| ${{ runner.os }}-pip- | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[dev]" | |
| pip install pytest-cov | |
| - name: Run tests with coverage | |
| run: | | |
| pytest tests/ \ | |
| -m "not slow and not real_api" \ | |
| --cov=src/polymarket_mcp \ | |
| --cov-report=xml \ | |
| --cov-report=html \ | |
| --cov-report=term-missing \ | |
| --cov-fail-under=80 \ | |
| --tb=short | |
| env: | |
| POLYGON_PRIVATE_KEY: "0000000000000000000000000000000000000000000000000000000000000001" | |
| POLYGON_ADDRESS: "0x0000000000000000000000000000000000000001" | |
| - name: Upload coverage to Codecov | |
| uses: codecov/codecov-action@v4 | |
| with: | |
| file: ./coverage.xml | |
| flags: unittests | |
| name: codecov-umbrella | |
| fail_ci_if_error: false | |
| - name: Upload HTML coverage report | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: coverage-report | |
| path: htmlcov/ | |
| # Integration tests with real API | |
| integration-test: | |
| name: Integration Tests | |
| runs-on: ubuntu-latest | |
| needs: [lint, test] | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION_DEFAULT }} | |
| - name: Cache pip packages | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.cache/pip | |
| key: ${{ runner.os }}-pip-integration-${{ hashFiles('**/pyproject.toml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pip-integration- | |
| ${{ runner.os }}-pip- | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[dev]" | |
| - name: Run integration tests | |
| run: | | |
| pytest tests/ -v -m "integration" \ | |
| --tb=short \ | |
| --timeout=120 | |
| env: | |
| POLYGON_PRIVATE_KEY: "0000000000000000000000000000000000000000000000000000000000000001" | |
| POLYGON_ADDRESS: "0x0000000000000000000000000000000000000001" | |
| POLYMARKET_CHAIN_ID: "137" | |
| - name: Test real API connectivity | |
| run: | | |
| python -c " | |
| import httpx | |
| import asyncio | |
| async def test(): | |
| async with httpx.AsyncClient() as client: | |
| # Test Gamma API | |
| response = await client.get('https://gamma-api.polymarket.com/markets', params={'limit': 1}) | |
| assert response.status_code == 200, f'Gamma API failed: {response.status_code}' | |
| print('✅ Gamma API connectivity OK') | |
| # Test CLOB API | |
| response = await client.get('https://clob.polymarket.com/ping') | |
| assert response.status_code == 200, f'CLOB API failed: {response.status_code}' | |
| print('✅ CLOB API connectivity OK') | |
| asyncio.run(test()) | |
| " | |
| # End-to-end tests | |
| e2e-test: | |
| name: End-to-End Tests | |
| runs-on: ubuntu-latest | |
| needs: integration-test | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION_DEFAULT }} | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[dev]" | |
| - name: Run E2E tests | |
| run: | | |
| pytest tests/test_e2e.py -v \ | |
| --tb=short \ | |
| --timeout=300 | |
| env: | |
| POLYGON_PRIVATE_KEY: "0000000000000000000000000000000000000000000000000000000000000001" | |
| POLYGON_ADDRESS: "0x0000000000000000000000000000000000000001" | |
| # Performance benchmarks | |
| performance-test: | |
| name: Performance Benchmarks | |
| runs-on: ubuntu-latest | |
| needs: test | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION_DEFAULT }} | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[dev]" | |
| pip install pytest-benchmark | |
| - name: Run performance tests | |
| run: | | |
| pytest tests/test_performance.py -v \ | |
| --benchmark-only \ | |
| --benchmark-json=benchmark.json | |
| env: | |
| POLYGON_PRIVATE_KEY: "0000000000000000000000000000000000000000000000000000000000000001" | |
| POLYGON_ADDRESS: "0x0000000000000000000000000000000000000001" | |
| - name: Upload benchmark results | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: benchmark-results | |
| path: benchmark.json | |
| # Docker build and test | |
| docker-test: | |
| name: Docker Build & Test | |
| runs-on: ubuntu-latest | |
| needs: lint | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Build Docker image | |
| run: | | |
| docker build -t polymarket-mcp:test . | |
| if: hashFiles('Dockerfile') != '' | |
| - name: Test Docker container | |
| run: | | |
| docker run --rm \ | |
| -e POLYGON_PRIVATE_KEY="0000000000000000000000000000000000000000000000000000000000000001" \ | |
| -e POLYGON_ADDRESS="0x0000000000000000000000000000000000000001" \ | |
| polymarket-mcp:test python -c "import polymarket_mcp; print('✅ Docker import OK')" | |
| if: hashFiles('Dockerfile') != '' | |
| # Install script testing | |
| install-script-test: | |
| name: Install Script Test | |
| runs-on: ${{ matrix.os }} | |
| needs: test | |
| timeout-minutes: 10 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION_DEFAULT }} | |
| - name: Test install script (if exists) | |
| run: | | |
| if [ -f "install.sh" ]; then | |
| bash install.sh --dry-run || echo "Install script dry-run completed" | |
| else | |
| echo "No install script found" | |
| fi | |
| - name: Test pip install | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e . | |
| python -c "import polymarket_mcp; print('✅ Package import OK')" | |
| # Tool count verification | |
| verify-tools: | |
| name: Verify Tool Count | |
| runs-on: ubuntu-latest | |
| needs: smoke-test | |
| timeout-minutes: 5 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION_DEFAULT }} | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e . | |
| - name: Verify tool count (read-only mode) | |
| run: | | |
| python -c " | |
| import sys | |
| sys.path.insert(0, 'src') | |
| from polymarket_mcp.tools import market_discovery, market_analysis, realtime | |
| tools = [] | |
| tools.extend(market_discovery.get_tools()) | |
| tools.extend(market_analysis.get_tools()) | |
| tools.extend(realtime.get_tools()) | |
| # In read-only mode: 8 Discovery + 10 Analysis + 7 Real-time = 25 tools | |
| assert len(tools) >= 25, f'Expected at least 25 tools (read-only), got {len(tools)}' | |
| print(f'✅ Verified {len(tools)} tools available (read-only mode)') | |
| " | |
| # Collect all results | |
| test-summary: | |
| name: Test Summary | |
| runs-on: ubuntu-latest | |
| needs: [smoke-test, lint, test, coverage, integration-test, e2e-test, performance-test, verify-tools] | |
| if: always() | |
| steps: | |
| - name: Check test results | |
| run: | | |
| echo "Test Summary:" | |
| echo "=============" | |
| echo "Smoke Test: ${{ needs.smoke-test.result }}" | |
| echo "Lint: ${{ needs.lint.result }}" | |
| echo "Unit Tests: ${{ needs.test.result }}" | |
| echo "Coverage: ${{ needs.coverage.result }}" | |
| echo "Integration: ${{ needs.integration-test.result }}" | |
| echo "E2E: ${{ needs.e2e-test.result }}" | |
| echo "Performance: ${{ needs.performance-test.result }}" | |
| echo "Tool Verification: ${{ needs.verify-tools.result }}" | |
| - name: Fail if any test failed | |
| if: | | |
| needs.smoke-test.result == 'failure' || | |
| needs.lint.result == 'failure' || | |
| needs.test.result == 'failure' || | |
| needs.coverage.result == 'failure' || | |
| needs.integration-test.result == 'failure' || | |
| needs.e2e-test.result == 'failure' | |
| run: exit 1 |