Merge pull request #211 from brownjuly2003-code/fix/batch-rate-limit-… #497
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: E2E Tests | |
| on: | |
| push: | |
| branches: [main] | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| jobs: | |
| e2e: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 12 | |
| env: | |
| AGENTFLOW_E2E_BASE_URL: http://127.0.0.1:8000 | |
| AGENTFLOW_E2E_CALLBACK_HOST: host.docker.internal | |
| AGENTFLOW_E2E_SUPPORT_KEY: af-prod-agent-support-abc123 | |
| AGENTFLOW_E2E_OPS_KEY: af-prod-agent-ops-def456 | |
| AGENTFLOW_E2E_RATE_LIMIT_KEY: af-prod-agent-rate-e2e000 | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 | |
| with: | |
| python-version: "3.11" | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| python -m pip install -e .[dev] | |
| python -m pip install -e ./sdk | |
| python -m pip install -r requirements.txt | |
| python -m pip install click rich pyyaml pytest-timeout | |
| - name: Prepare pytest temp directory | |
| run: mkdir -p .tmp | |
| - name: Start E2E stack | |
| run: | | |
| docker compose -f docker-compose.e2e.yml up -d --build agentflow-api | |
| python - <<'PY' | |
| import json | |
| import subprocess | |
| import time | |
| def parse_compose_ps_output(stdout): | |
| payload = (stdout or "").strip() | |
| if not payload: | |
| return [] | |
| decoder = json.JSONDecoder() | |
| entries = [] | |
| index = 0 | |
| while index < len(payload): | |
| entry, index = decoder.raw_decode(payload, index) | |
| if isinstance(entry, list): | |
| entries.extend(entry) | |
| else: | |
| entries.append(entry) | |
| while index < len(payload) and payload[index].isspace(): | |
| index += 1 | |
| return entries | |
| compose_ps_command = ["docker", "compose", "-f", "docker-compose.e2e.yml", "ps", "--format", "json"] | |
| required = {"agentflow-api", "redis", "kafka", "postgres", "clickhouse"} | |
| deadline = time.monotonic() + 180 | |
| while time.monotonic() < deadline: | |
| result = subprocess.run( | |
| compose_ps_command, | |
| check=False, | |
| capture_output=True, | |
| text=True, | |
| ) | |
| if result.returncode == 0: | |
| try: | |
| entries = parse_compose_ps_output(result.stdout) | |
| except json.JSONDecodeError: | |
| entries = [] | |
| services = {entry["Service"]: entry for entry in entries} | |
| if required.issubset(services): | |
| all_healthy = all( | |
| services[name].get("State") == "running" | |
| and ( | |
| services[name].get("Health") == "healthy" | |
| or "(healthy)" in services[name].get("Status", "") | |
| ) | |
| for name in required | |
| ) | |
| if all_healthy: | |
| break | |
| time.sleep(2) | |
| else: | |
| subprocess.run( | |
| ["docker", "compose", "-f", "docker-compose.e2e.yml", "ps"], | |
| check=False, | |
| ) | |
| raise SystemExit("E2E compose services did not become healthy within 180 seconds.") | |
| PY | |
| python scripts/wait_for_services.py --url "$AGENTFLOW_E2E_BASE_URL" --timeout 120 | |
| - name: Run E2E tests | |
| run: pytest tests/e2e/ -v --tb=short --timeout=60 | |
| # The one-shot serving-init service provisions and seeds ClickHouse | |
| # before the API starts (the API itself no longer touches the store on | |
| # boot — audit P0-2), so rows in agentflow.orders_v2 prove the E2E stack | |
| # exercised the real engine, not a DuckDB fallback. | |
| - name: Verify ClickHouse serving path | |
| run: | | |
| orders=$(docker compose -f docker-compose.e2e.yml exec -T clickhouse \ | |
| clickhouse-client --query "SELECT count() FROM agentflow.orders_v2") | |
| echo "agentflow.orders_v2 rows: $orders" | |
| test "$orders" -gt 0 | |
| events_table=$(docker compose -f docker-compose.e2e.yml exec -T clickhouse \ | |
| clickhouse-client --query "EXISTS TABLE agentflow.pipeline_events") | |
| echo "agentflow.pipeline_events exists: $events_table" | |
| test "$events_table" = "1" | |
| - name: Collect logs on failure | |
| if: failure() | |
| run: docker compose -f docker-compose.e2e.yml logs --tail=500 > e2e-logs.txt | |
| - name: Upload logs | |
| if: failure() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: e2e-logs | |
| path: e2e-logs.txt | |
| - name: Stop API | |
| if: always() | |
| run: | | |
| docker compose -f docker-compose.e2e.yml down -v |