Development and Testing
May 27, 2026 · View on GitHub
This document collects the local development workflow and the repository's test entry points in one place.
Prerequisites
- Go 1.26 or later
- Docker, for integration tests (including OAuth e2e tests)
- A local or reachable ClickHouse server, if you want to run
test-connectionmanually
Build
Build the main binary:
go build -o altinity-mcp ./cmd/altinity-mcp
Check the current build:
./altinity-mcp version
Quick Local Check
Validate that the binary can reach ClickHouse before running broader tests:
./altinity-mcp test-connection \
--clickhouse-host localhost \
--clickhouse-port 8123 \
--clickhouse-database default
Test Matrix
Full Default Suite
Run the default repository test suite:
go test ./...
This is the baseline command for day-to-day work. It runs unit tests plus the Docker-backed integration tests that are enabled by default in the repository.
Package-Focused Runs
Run package tests only:
go test ./pkg/...
Run CLI and HTTP handler tests:
go test -v ./cmd/altinity-mcp/...
Run OAuth-focused tests only:
go test ./pkg/server ./cmd/altinity-mcp ./pkg/config -run OAuth -count=1 -v
Docker-Backed Integration Tests
Several tests start temporary ClickHouse containers with testcontainers-go. Before running them, make sure Docker is running and the current user can access the Docker socket.
If Docker is unavailable, the default suite will not be reliable.
OAuth End-to-End Tests
OAuth e2e tests validate bearer-token authentication through MCP to ClickHouse. They use a lightweight in-process mock OIDC provider and an altinity/clickhouse-server:25.8.16.20001.altinityantalya container (required for token_processors support — standard ClickHouse images do not include it).
These tests run automatically as part of go test ./... (skipped with -short).
For configuration background and provider-specific setup, see oauth_authorization.md.
Embedded ClickHouse for Tests
Tests under internal/testutil/embeddedch boot ClickHouse as a host subprocess instead of a container. Two flavors are supported:
- Stock — upstream ClickHouse, downloaded automatically by
franchb/embedded-clickhouse. - Antalya — the Altinity Antalya binary, expected at
~/.cache/embedded-clickhouse/clickhouse-<sanitized-image-tag>.
On Linux the Antalya binary is extracted once from the Antalya Docker image (altinity/clickhouse-server:26.1.6.20001.altinityantalya) on first use.
On macOS and other non-Linux hosts you must build it from source ahead of time — the Antalya Docker image only ships a Linux ELF, so it cannot run as a host subprocess on macOS.
Antalya binary on macOS
Antalya does not publish macOS Docker images, so the binary cannot be auto-extracted on darwin. Build it once from source — see build_antalya_macos.md for the full guide — then place it in the test cache as described below.
Pin the checkout to AntalyaImageRef
altinity-mcp's tests look for a binary that matches the AntalyaImageRef constant in internal/testutil/embeddedch/embeddedch.go. Derive the matching tag from the source so the build stays in lockstep:
ANTALYA_IMAGE_REF=$(grep -E '^\s*const AntalyaImageRef' internal/testutil/embeddedch/embeddedch.go | sed -E 's/.*"([^"]+)".*/\1/')
ANTALYA_IMAGE_TAG="v${ANTALYA_IMAGE_REF##*:}"
echo "image=$ANTALYA_IMAGE_REF tag=$ANTALYA_IMAGE_TAG"
In the build guide's git checkout step, use "$ANTALYA_IMAGE_TAG" instead of a moving branch like antalya-26.1. Keep this shell session open — $ANTALYA_IMAGE_REF is reused below.
Install the built binary into the cache
After the build produces build/programs/clickhouse:
mkdir -p ~/.cache/embedded-clickhouse
ANTALYA_BIN_SUFFIX=$(printf '%s' "$ANTALYA_IMAGE_REF" | LC_ALL=C sed -E 's/[^A-Za-z0-9._-]/_/g')
DEST=~/.cache/embedded-clickhouse/clickhouse-${ANTALYA_BIN_SUFFIX}
cp /path/to/ClickHouse/build/programs/clickhouse "$DEST"
chmod +x "$DEST"
echo "installed: $DEST"
The filename suffix mirrors safeFileName(AntalyaImageRef) in the Go code — every char outside [A-Za-z0-9._-] becomes _. If unsure, run the tests once; the failure message prints the exact path it expected.
Verify
go test ./pkg/server/... -run Antalya -count=1 -v
Refresh after AntalyaImageRef bumps
Re-run the "Pin the checkout" snippet to refresh $ANTALYA_IMAGE_REF/$ANTALYA_IMAGE_TAG, then redo the build (git checkout the new tag, git submodule update, possibly install a new pinned Rust nightly), and re-run the install step. The cached binary is keyed by AntalyaImageRef, so the old file is harmless to leave behind.
Suggested Contributor Workflow
For a typical code change:
- Build the binary with
go build -o altinity-mcp ./cmd/altinity-mcp - Run focused tests for the area you changed
- Run
go test ./... - OAuth e2e tests run automatically — no extra flags needed
Troubleshooting
Docker Tests Fail Immediately
- Verify Docker is running
- Verify container pulls are allowed from the current environment
- Re-run the failing package with
-vto see which container-backed test failed
OAuth E2E Test Fails with Standard ClickHouse Images
The OAuth e2e tests require the Antalya ClickHouse build (altinity/clickhouse-server:25.8.16.20001.altinityantalya). Standard upstream images do not provide the token_processors support these tests depend on. The test pulls this image automatically via testcontainers.