Skip to content

Docker E2E Testing

Docker E2E mode starts a disposable GitLab environment, provisions fixtures, registers a CI runner, and runs the MCP end-to-end suite against that local instance. The default path uses GitLab CE; Enterprise mode uses the EE image plus a local Ultimate license. Use it when you need high-confidence validation without relying on a real .env GitLab instance.

| Component | Purpose | | --------------- | -------------------------------------------------------------------------------------- | | GitLab CE or EE | Ephemeral GitLab instance for real REST and GraphQL API calls | | GitLab Runner | Enables pipeline and job workflows that unit tests cannot exercise | | Fixture service | Provides deterministic webhook, custom emoji, and mirror endpoints | | E2E suite | Runs individual, meta-tool, and dynamic tool workflows through in-memory MCP transport |

Docker mode covers the same lifecycle workflows as self-hosted E2E plus Docker-only pipeline and job scenarios. It creates temporary GitLab data and removes it when the stack is torn down.

Terminal window
make test-e2e-docker

That target orchestrates the Docker stack, waits for GitLab, configures the test user and runner, runs the Go E2E suite with the e2e build tag, and writes JUnit plus JSON reports.

To run the Enterprise/Premium coverage against GitLab EE, set ENTERPRISE_LICENSE in .env or your shell and use:

Terminal window
make test-e2e-docker-enterprise

That target runs with the e2e enterprise build tags, so common harness files plus test/e2e/suite/*_ee_test.go Enterprise/Premium tests are compiled and executed. CE-only tests live in test/e2e/suite/*_ce_test.go and stay in make test-e2e-docker, while Enterprise fixtures can be tuned independently.

When ENTERPRISE_LICENSE contains a 24-character activation code, the first successful run exports the generated reusable license key to test/e2e/.enterprise-license. Later Enterprise runs prefer that ignored local cache and install it through the License API, so they do not need to spend the activation code again.

Use the manual sequence when you need to inspect the GitLab UI or rerun a focused test without recreating the stack every time.

Terminal window
docker compose -f test/e2e/docker-compose.yml up -d
./test/e2e/scripts/wait-for-gitlab.sh
./test/e2e/scripts/setup-gitlab.sh
./test/e2e/scripts/register-runner.sh
set -a && source test/e2e/.env.docker && set +a
go test -v -tags e2e -timeout 600s ./test/e2e/suite/
docker compose -f test/e2e/docker-compose.yml down -v

For manual Enterprise setup, replace the compose commands with the EE image and set the edition flag during provisioning:

Terminal window
env GITLAB_IMAGE=gitlab/gitlab-ee:latest docker compose -f test/e2e/docker-compose.yml up -d
GITLAB_ENTERPRISE=true ./test/e2e/scripts/setup-gitlab.sh
env GITLAB_IMAGE=gitlab/gitlab-ee:latest docker compose -f test/e2e/docker-compose.yml down -v

To run only the dynamic tool surface workflow after setup:

Terminal window
E2E_MODE=docker \
go test -v -tags e2e -timeout 600s \
-run '^TestDynamicToolSurface' \
./test/e2e/suite/

| Situation | Use Docker E2E? | | ----------------------------------------------------------------- | --------------- | | Changing tool registration, catalog projection, or schemas | Yes | | Changing pipeline, job, webhook, custom emoji, or mirror behavior | Yes | | Verifying release candidates before publishing binaries | Yes | | Editing a narrow Markdown page only | Usually no | | Debugging a failing unit test with mocked GitLab responses | Usually no |

The suite writes machine-readable reports for CI and local triage. If a run fails, keep the Docker stack up while inspecting GitLab data, runner logs, and the generated E2E report files. When finished, remove all test data with:

Terminal window
docker compose -f test/e2e/docker-compose.yml down -v

| Symptom | What to check | | ----------------------------------------- | --------------------------------------------------------------------------- | | GitLab never becomes ready | Docker memory and CPU limits; GitLab needs several GB of RAM | | Enterprise scenarios are not enabled | GITLAB_ENTERPRISE=true, the EE image, and ENTERPRISE_LICENSE in .env | | Pipeline or job tests are skipped/failing | Runner registration output and test/e2e/.env.docker values | | Webhook or mirror tests fail | Fixture service container health and internal Docker network URLs | | A rerun sees stale data | Run docker compose -f test/e2e/docker-compose.yml down -v and start again |

Docker E2E is slower than unit tests, but it is the preferred validation path for architecture migrations because it exercises the real GitLab API, the MCP transport, and every public tool surface together.