-
Notifications
You must be signed in to change notification settings - Fork 22
feat: add local E2E sanity test harness #461
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+1,266
−1
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| # Required for smoke tests (LLM-dependent) | ||
| # WARNING: Never commit real credentials. Use secrets management for production. | ||
| ANTHROPIC_API_KEY=your-api-key-here | ||
|
|
||
| # Optional: Snowflake credentials for cloud warehouse testing | ||
| # ALTIMATE_CODE_CONN_SNOWFLAKE_TEST='{"account":"...","user":"...","password":"...","warehouse":"...","database":"..."}' |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| FROM oven/bun:1.3.10-debian | ||
|
|
||
| # System deps (what a real user would have) | ||
| RUN apt-get update && apt-get install -y \ | ||
| git python3 python3-pip python3-venv curl sqlite3 \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
|
|
||
| # dbt in venv (matches real user setup) | ||
| RUN python3 -m venv /opt/dbt && \ | ||
| /opt/dbt/bin/pip install --quiet dbt-core dbt-duckdb dbt-postgres | ||
| ENV PATH="/opt/dbt/bin:$PATH" | ||
|
|
||
| # Fresh user, clean HOME — simulates new user | ||
| ENV HOME=/home/testuser | ||
| RUN useradd -m testuser | ||
| USER testuser | ||
| WORKDIR /home/testuser | ||
|
|
||
| # Copy the built binary directly (simulates what postinstall does) | ||
| # The real npm publish pipeline rewrites workspace:* deps — we can't use npm pack directly. | ||
| # Instead, copy the built binary + run postinstall manually. | ||
| COPY --chown=testuser packages/opencode/dist/@altimateai/ /home/testuser/.altimate-install/dist/@altimateai/ | ||
| COPY --chown=testuser packages/opencode/script/postinstall.mjs /home/testuser/.altimate-install/postinstall.mjs | ||
| COPY --chown=testuser packages/opencode/package.json /home/testuser/.altimate-install/package.json | ||
| COPY --chown=testuser .opencode/skills/ /home/testuser/.altimate-install/skills/ | ||
|
|
||
| # Install altimate-core native binding (required at runtime) | ||
| RUN cd /home/testuser/.altimate-install && \ | ||
| echo '{"dependencies":{"@altimateai/altimate-core":"latest"}}' > package.json && \ | ||
| bun install && \ | ||
| node -e "require('@altimateai/altimate-core')" 2>/dev/null || { echo "FATAL: altimate-core install failed"; exit 1; } | ||
|
|
||
| # Link binary to PATH and copy skills to ~/.altimate/builtin/ | ||
| # Detect architecture: use TARGETARCH from docker buildx, fall back to uname | ||
| ARG TARGETARCH | ||
| RUN ARCH="${TARGETARCH:-$(uname -m | sed 's/x86_64/x64/' | sed 's/aarch64/arm64/')}" && \ | ||
| mkdir -p /home/testuser/.local/bin && \ | ||
| cp /home/testuser/.altimate-install/dist/@altimateai/altimate-code-linux-${ARCH}/bin/altimate /home/testuser/.local/bin/altimate && \ | ||
| chmod +x /home/testuser/.local/bin/altimate && \ | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| mkdir -p /home/testuser/.altimate/builtin && \ | ||
| cp -r /home/testuser/.altimate-install/skills/* /home/testuser/.altimate/builtin/ | ||
| ENV PATH="/home/testuser/.local/bin:$PATH" | ||
| ENV NODE_PATH="/home/testuser/.altimate-install/node_modules" | ||
|
|
||
| # Copy test scripts | ||
| COPY --chown=testuser test/sanity/ /home/testuser/sanity/ | ||
| RUN chmod +x /home/testuser/sanity/run.sh \ | ||
| /home/testuser/sanity/phases/*.sh \ | ||
| /home/testuser/sanity/pr-tests/*.sh \ | ||
| /home/testuser/sanity/lib/*.sh | ||
|
|
||
| ENTRYPOINT ["/home/testuser/sanity/run.sh"] | ||
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| FROM oven/bun:1.3.10-debian | ||
|
|
||
| RUN apt-get update && apt-get install -y \ | ||
| git python3 python3-pip python3-venv curl sqlite3 \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
|
|
||
| RUN python3 -m venv /opt/dbt && \ | ||
| /opt/dbt/bin/pip install --quiet dbt-core dbt-duckdb dbt-postgres | ||
| ENV PATH="/opt/dbt/bin:$PATH" | ||
|
|
||
| ENV HOME=/home/testuser | ||
| RUN useradd -m testuser | ||
| USER testuser | ||
| WORKDIR /home/testuser | ||
|
|
||
| # Install previous version first | ||
| ARG PRIOR_VERSION=latest | ||
| RUN npm install -g @altimateai/altimate-code@${PRIOR_VERSION} | ||
kulvirgit marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| # Record old version for comparison | ||
| RUN altimate --version > /tmp/old-version.txt 2>/dev/null || echo "unknown" > /tmp/old-version.txt | ||
|
|
||
| # Run once to seed DB, config, session data | ||
| RUN git init /tmp/seed-project && \ | ||
| cd /tmp/seed-project && \ | ||
| git config user.name "seed" && \ | ||
| git config user.email "seed@test.local" && \ | ||
| echo '{}' > package.json && \ | ||
| git add -A && git commit -q -m "seed" | ||
|
|
||
| # Upgrade to new version | ||
| COPY --chown=testuser dist/package.tgz /tmp/altimate-code.tgz | ||
| RUN npm install -g /tmp/altimate-code.tgz | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| # Copy test scripts | ||
| COPY --chown=testuser test/sanity/ /home/testuser/sanity/ | ||
| RUN chmod +x /home/testuser/sanity/run.sh \ | ||
| /home/testuser/sanity/phases/*.sh \ | ||
| /home/testuser/sanity/pr-tests/*.sh \ | ||
| /home/testuser/sanity/lib/*.sh | ||
|
|
||
| ENV OLD_VERSION_FILE=/tmp/old-version.txt | ||
|
|
||
| ENTRYPOINT ["/home/testuser/sanity/run.sh", "--upgrade"] | ||
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,119 @@ | ||
| #!/bin/bash | ||
| # Local CI pipeline — ports .github/workflows/ci.yml to run locally | ||
| set -euo pipefail | ||
|
|
||
| MODE="${1:-fast}" | ||
| REPO_ROOT="$(cd "$(dirname "$0")/../.." && pwd)" | ||
| EXIT_CODE=0 | ||
|
|
||
| # Ensure Docker containers are cleaned up on exit (full/pr modes) | ||
| cleanup_docker() { | ||
| docker compose -f "$REPO_ROOT/test/sanity/docker-compose.yml" down --volumes --remove-orphans 2>/dev/null || true | ||
| } | ||
| trap cleanup_docker EXIT | ||
|
|
||
| echo "========================================" | ||
| echo " Local CI Pipeline — mode: $MODE" | ||
| echo " Time: $(date -u +%Y-%m-%dT%H:%M:%SZ)" | ||
| echo "========================================" | ||
|
|
||
| run_step() { | ||
| local name="$1"; shift | ||
| echo "" | ||
| echo "--- $name ---" | ||
| if "$@"; then | ||
| echo " >>> $name: PASSED" | ||
| else | ||
| echo " >>> $name: FAILED" | ||
| EXIT_CODE=1 | ||
| fi | ||
| } | ||
|
|
||
| # ── Fast mode (default — what pre-push hook runs) ────────────── | ||
|
|
||
| echo "" | ||
| echo "=== Fast CI ===" | ||
|
|
||
| run_step "Typecheck" bun turbo typecheck | ||
|
|
||
| run_step "Unit Tests (opencode)" bash -c "cd $REPO_ROOT/packages/opencode && bun test --timeout 30000" | ||
|
|
||
| run_step "Unit Tests (dbt-tools)" bash -c "cd $REPO_ROOT/packages/dbt-tools && bun run test" | ||
|
|
||
| # Marker guard (needs upstream remote) | ||
| if git remote | grep -q upstream; then | ||
| run_step "Marker Guard" bun run "$REPO_ROOT/script/upstream/analyze.ts" --markers --base origin/main --strict | ||
| else | ||
| echo "" | ||
| echo "--- Marker Guard ---" | ||
| echo " SKIP: upstream remote not configured" | ||
| fi | ||
|
|
||
| # ── Full mode ────────────────────────────────────────────────── | ||
|
|
||
| if [ "$MODE" = "--full" ] || [ "$MODE" = "full" ]; then | ||
| echo "" | ||
| echo "=== Full CI (Docker) ===" | ||
|
|
||
| # Driver E2E with Docker containers | ||
| run_step "Docker Services Up" docker compose -f "$REPO_ROOT/test/sanity/docker-compose.yml" up -d postgres mysql mssql redshift | ||
|
|
||
| echo " Waiting for services to be healthy..." | ||
| HEALTHY=0 | ||
| for _wait in $(seq 1 30); do | ||
| HEALTHY=$(docker compose -f "$REPO_ROOT/test/sanity/docker-compose.yml" ps --format json 2>/dev/null | grep -c '"healthy"' || echo "0") | ||
| if [ "$HEALTHY" -ge 4 ]; then break; fi | ||
| sleep 2 | ||
| done | ||
|
|
||
| if [ "$HEALTHY" -lt 4 ]; then | ||
| echo " >>> Docker Services: FAILED ($HEALTHY/4 healthy after 60s)" | ||
| EXIT_CODE=1 | ||
| else | ||
| echo " >>> Docker Services: $HEALTHY/4 healthy" | ||
| fi | ||
|
|
||
| # Skip driver tests if services aren't healthy | ||
| if [ "$HEALTHY" -lt 4 ]; then | ||
| echo " SKIP: Driver E2E tests (services not healthy)" | ||
| else | ||
|
|
||
| run_step "Driver E2E (local)" bash -c "cd $REPO_ROOT/packages/opencode && \ | ||
| TEST_PG_HOST=127.0.0.1 TEST_PG_PORT=15432 TEST_PG_PASSWORD=testpass123 \ | ||
| bun test test/altimate/drivers-e2e.test.ts --timeout 30000" | ||
|
|
||
| run_step "Driver E2E (docker)" bash -c "cd $REPO_ROOT/packages/opencode && \ | ||
| TEST_MYSQL_HOST=127.0.0.1 TEST_MYSQL_PORT=13306 TEST_MYSQL_PASSWORD=testpass123 \ | ||
| TEST_MSSQL_HOST=127.0.0.1 TEST_MSSQL_PORT=11433 TEST_MSSQL_PASSWORD='TestPass123!' \ | ||
| TEST_REDSHIFT_HOST=127.0.0.1 TEST_REDSHIFT_PORT=15439 TEST_REDSHIFT_PASSWORD=testpass123 \ | ||
| bun test test/altimate/drivers-docker-e2e.test.ts --timeout 30000" | ||
|
|
||
| # Full sanity suite in Docker | ||
| run_step "Sanity Suite (Docker)" docker compose -f "$REPO_ROOT/test/sanity/docker-compose.yml" \ | ||
| up --build --abort-on-container-exit --exit-code-from sanity | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| fi # end healthy gate | ||
| fi | ||
|
|
||
| # ── PR mode ──────────────────────────────────────────────────── | ||
|
|
||
| if [ "$MODE" = "--pr" ] || [ "$MODE" = "pr" ]; then | ||
| echo "" | ||
| echo "=== PR-Aware Tests ===" | ||
|
|
||
| run_step "Generate PR tests" bash "$REPO_ROOT/test/sanity/pr-tests/generate.sh" origin/main | ||
| run_step "Run PR tests" bash "$REPO_ROOT/test/sanity/pr-tests/run-pr-tests.sh" | ||
| fi | ||
|
|
||
| # ── Summary ──────────────────────────────────────────────────── | ||
|
|
||
| echo "" | ||
| echo "========================================" | ||
| if [ $EXIT_CODE -eq 0 ]; then | ||
| echo " LOCAL CI: ALL PASSED" | ||
| else | ||
| echo " LOCAL CI: SOME STEPS FAILED" | ||
| fi | ||
| echo "========================================" | ||
|
|
||
| exit $EXIT_CODE | ||
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| # Override for upgrade testing — replaces sanity service with Dockerfile.upgrade | ||
| services: | ||
| sanity: | ||
| build: | ||
| context: ../.. | ||
| dockerfile: test/sanity/Dockerfile.upgrade | ||
| args: | ||
| PRIOR_VERSION: ${PRIOR_VERSION:-latest} |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| services: | ||
| sanity: | ||
| build: | ||
| context: ../.. | ||
| dockerfile: test/sanity/Dockerfile | ||
| environment: | ||
| - ANTHROPIC_API_KEY | ||
| - ALTIMATE_CODE_CONN_SNOWFLAKE_TEST | ||
| - TEST_PG_HOST=postgres | ||
| - TEST_PG_PORT=5432 | ||
| - TEST_PG_PASSWORD=testpass123 | ||
| - TEST_MYSQL_HOST=mysql | ||
| - TEST_MYSQL_PORT=3306 | ||
| - TEST_MYSQL_PASSWORD=testpass123 | ||
| - TEST_MSSQL_HOST=mssql | ||
| - TEST_MSSQL_PORT=1433 | ||
| - TEST_MSSQL_PASSWORD=TestPass123! | ||
| - TEST_REDSHIFT_HOST=redshift | ||
| - TEST_REDSHIFT_PORT=5432 | ||
| - TEST_REDSHIFT_PASSWORD=testpass123 | ||
| depends_on: | ||
| postgres: | ||
| condition: service_healthy | ||
| mysql: | ||
| condition: service_healthy | ||
| mssql: | ||
| condition: service_healthy | ||
| redshift: | ||
| condition: service_healthy | ||
|
|
||
| postgres: | ||
| image: postgres:16-alpine | ||
| environment: | ||
| POSTGRES_PASSWORD: testpass123 | ||
| ports: | ||
| - "15432:5432" | ||
| healthcheck: | ||
| test: pg_isready | ||
| interval: 5s | ||
| retries: 10 | ||
|
|
||
| mysql: | ||
| image: mysql:8.0 | ||
| environment: | ||
| MYSQL_ROOT_PASSWORD: testpass123 | ||
| MYSQL_DATABASE: testdb | ||
| ports: | ||
| - "13306:3306" | ||
| healthcheck: | ||
| test: mysqladmin ping -h 127.0.0.1 | ||
| interval: 5s | ||
| retries: 20 | ||
|
|
||
| mssql: | ||
| image: mcr.microsoft.com/azure-sql-edge:latest | ||
| environment: | ||
| ACCEPT_EULA: "Y" | ||
| MSSQL_SA_PASSWORD: "TestPass123!" | ||
| ports: | ||
| - "11433:1433" | ||
| healthcheck: | ||
| test: /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P 'TestPass123!' -Q 'SELECT 1' || exit 1 | ||
| interval: 10s | ||
| retries: 20 | ||
|
|
||
| redshift: | ||
| image: postgres:16-alpine | ||
| environment: | ||
| POSTGRES_PASSWORD: testpass123 | ||
| POSTGRES_DB: dev | ||
| ports: | ||
| - "15439:5432" | ||
| healthcheck: | ||
| test: pg_isready | ||
| interval: 5s | ||
| retries: 10 |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| { | ||
| "provider": { | ||
| "anthropic": { | ||
| "api_key": 12345 | ||
| } | ||
| }, | ||
| "experimental": { | ||
| "not_a_real_field": "should be ignored", | ||
| "auto_mcp_discovery": "not-a-boolean" | ||
| }, | ||
| "unknown_top_level": true | ||
| } |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| -- Seed a large session to test compaction circuit breaker | ||
| -- This creates a session with enough message data to trigger isOverflow() | ||
| -- Note: This is a minimal seed — actual compaction depends on token counting | ||
| -- which requires the LLM provider. This just ensures the DB structure is valid. | ||
|
|
||
| INSERT OR IGNORE INTO session (id, project_id, slug, directory, title, version, time_created, time_updated) | ||
| VALUES ('ses_sanity_compaction_test', 'proj_sanity', 'sanity-compaction', '/tmp', 'Compaction Test Session', 1, strftime('%s','now') * 1000, strftime('%s','now') * 1000); |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| { | ||
| "provider": { | ||
| "anthropic": { | ||
| "api_key": "test-key-not-real" | ||
| } | ||
| }, | ||
| "experimental": { | ||
| "auto_mcp_discovery": true | ||
| } | ||
| } |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| -- Known anti-patterns for sql_analyze sanity testing | ||
| -- SELECT * is a classic anti-pattern that should always be flagged | ||
| SELECT * FROM users WHERE id IN (1, 2, 3, 4, 5); | ||
|
|
||
| -- Implicit join (cartesian product risk) | ||
| SELECT u.name, o.total FROM users u, orders o WHERE u.id = o.user_id; |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.