Skip to content

ci: Speed up the smoke test - #1468

Closed
marcleblanc2 wants to merge 7 commits into
mainfrom
speed-up-ci-smoke-test
Closed

marcleblanc2 wants to merge 7 commits into
mainfrom
speed-up-ci-smoke-test

Conversation

@marcleblanc2

@marcleblanc2 marcleblanc2 commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

The :rice: docker-compose-test job took 7.5 to 10 minutes on every PR. Most of that was waiting, not testing. This PR removes the waits we control from this repo.

The job took 228s to 353s on this PR's five builds (16811, 16813, 16814, 16816, 16822), against 458s to 594s on the 14 passing builds before it (16794-16810).

Phase Before After Change
Install Vagrant plugins 43-48s 1s (17s for the first job on a new agent host) Install vagrant-google only if it's missing (agents on a host share ~/.vagrant.d). Drop vagrant-env: there is no test/.env to load. Install vagrant-scp only when the test fails and we need the logs.
Create VM, wait for SSH 45-57s 50-73s (177s once) None. See the note on build 16811 below.
Pull 23 images 121-145s 81-125s docker-compose pull before up. Compose v1 up pulls one image at a time; pull runs in parallel.
Create containers 43-49s 45-56s None
Wait for startup 90s 10-31s Replace sleep 90: poll every 5s until /healthz responds and no container health check is starting or unhealthy. Fails after 5 minutes.
Tests 3-4s 3-4s New check: no container has restarted.
Delete VM 64-125s 3-6s Send the delete request to the GCE API and exit, instead of waiting for the VM to shut down. Falls back to vagrant destroy if the request fails.
Whole job 458-594s 228-353s

Also:

  • Skip the smoke test on branches which only change *.md files (if_changed). The compose validation and prettier steps still run. Builds on main always run the smoke test.
  • Print docker-compose version in the smoke test log. The e2e image ships Compose 1.29.2.
  • Stop cancelled builds leaking VMs and disks. See below.

Leaked VMs and disks

sourcegraph-ci holds three old test VMs and three unattached test disks. Vagrant creates the boot disk, then the VM, and only records the VM once GCP has finished creating it, about 20s later. A build cancelled inside that window ran vagrant destroy, which replied "Instance is not created", and deleted nothing. Build 16663 leaked docker-test-179202280492015 this way on 2026-10-15, a 16 vCPU VM which is still running.

  • The VM and its disk are now named docker-test-job-<Buildkite job ID>, so the cleanup deletes them by name, without asking Vagrant. It deletes the VM, or the disk if no VM uses it.
  • A job which is killed before its cleanup finishes (a lost agent, for example) still leaks. So every job first deletes docker-test-job-* VMs, and unattached disks, older than an hour. The smoke test step now times out after 30 minutes, so nothing that old belongs to a running job.
  • The sweep only matches the new names. It leaves the six old resources alone; they need deleting by hand.
  • GCE can delete a VM by itself after a time limit (maxRunDuration with instanceTerminationAction: DELETE), but only if it is set when the VM is created, and vagrant-google 2.7.0 can't set it. Creating the VM with gcloud compute instances create --max-run-duration instead of Vagrant would replace the sweep.

Things to know

  • 11 of the 25 containers define a health check. The other 14 (caddy, gitserver, zoekt-indexserver, worker, prometheus, grafana, cadvisor, node-exporter, the three database exporters, both redis containers, otel-collector) are only checked for being up.
  • The wait is stricter than the old sleep: a container which stays unhealthy now fails the test. It is also shorter, so the test looks at the containers about a minute sooner. To make up for that, the test now fails if any container has restarted, which catches a crash-loop however quickly we look. A container without a health check, which first crashes more than about 30s after starting, would have been caught by the 90s sleep, and is not caught now.
  • The smoke test step is defined twice, with a YAML anchor: once for main (always runs), once for other branches (if_changed). Each build shows the one which doesn't apply as a greyed-out job. if_changed compares against origin/main, so on main it would find no changes in any commit but the newest, and skip the test.
  • The Buildkite pipeline's settings still name master as the default branch. Builds without a pull request therefore can't work out a diff, and run every step. So the docs-only skip only applies once the pull request is open. Fixing the setting makes the skip work on the first push too.
  • Removing config.env.enable means a local vagrant up no longer reads test/.env. Nothing documented that file; the deleted TESTING.md told developers to export the variables.
  • Build 16811 waited 153s for SSH on the new VM; the other 19 builds I measured waited 20-49s. Nothing in this PR touches the VM's boot, so I'm treating it as a slow boot.
  • The second and third commits try, then revert, a pd-balanced boot disk. It didn't speed up the pulls (89s, against 93s on pd-standard).

Checklist

  • All images have a valid tag and SHA256 sum (no image changes)

Test plan

  • Ran the cleanup and the sweep from .buildkite/vagrant-run.sh locally against stubbed vagrant, gcloud, and curl, covering: nothing to delete, a VM, an unattached disk (each sends the delete requests, and skips vagrant destroy), and a failing instance list, disk list, or delete request (each falls back to vagrant destroy)
  • All seven Buildkite builds on this PR passed, and none fell back to vagrant destroy. Build 16829 is the first with the job-named VM
  • Cancelled while GCP created the VM: build 16834 (throwaway branch) got the cancel signal 13s after "Launching an instance", before Vagrant had recorded the VM. This is the window which leaked a VM in build 16663. The cleanup found the VM by name, and GCP deleted it. Build 16833, cancelled while it waited for SSH, deleted its VM the same way
  • Not exercised against GCP: a cancel between the disk's creation and the VM's (a 2-3s window), a delete request while the VM's creation is still in progress, and the sweep finding something to delete. The stubbed run covers the script's side of all three
  • VM deletion: gcloud compute operations list --project=sourcegraph-ci shows a completed delete for every VM these builds created, including the VM of a build which was cancelled while it waited for SSH (16820)
  • New agent host: builds 16816 and 16820 landed on hosts without the plugin, and installed it. Build 16817 (throwaway branch) ran with an empty VAGRANT_HOME, and passed
  • Failing test: build 16818 (throwaway branch) crash-looped node-exporter. The job failed with exit status 1, installed vagrant-scp, copied node-exporter.log from the VM, uploaded it as an artifact, and deleted the VM
  • Docs-only skip: build 16821 (test: Docs-only change, to check the smoke test is skipped (do not merge) #1469, a throwaway pull request against this branch, changing one .md file) skipped the smoke test, and passed in 15s. Build 16820, the same branch before Buildkite knew about the pull request, ran it
  • Build on main, simulated: build 16844 (TEMPORARY: CI test for #1468, do not merge #1476, a throwaway pull request) ran this branch with main replaced by the throwaway branch's name in both if conditions, and changed one .md file. if_changed found the one changed file. The always-run step still ran the smoke test, and passed; the branch step was skipped. Build 16821 skipped the smoke test for the same kind of change
  • Not exercised: a build on the real main branch. That needs a merge, or a Buildkite token which can create builds

Skip waiting on the VM deletion, poll container health instead of sleeping
90 seconds, pull images in parallel, install fewer Vagrant plugins, and
skip the smoke test on docs-only builds.

Amp-Thread-ID: https://ampcode.com/threads/T-01a1c731-7931-7091-9b5e-664cc2379c79
Co-authored-by: Amp <amp@ampcode.com>
@github-actions

github-actions Bot commented Nov 10, 2026 •

Copy link
Copy Markdown

marcleblanc2 and others added 3 commits November 10, 2026 15:24
Measured on build 16813: image pulls took 90s, against 93s on pd-standard
in build 16811, so the disk is not what limits them.

Amp-Thread-ID: https://ampcode.com/threads/T-01a1c731-7931-7091-9b5e-664cc2379c79
Co-authored-by: Amp <amp@ampcode.com>
if_changed compares a build against origin/main. For a commit which is
already on main, and is not the newest, that comparison is empty, so the
smoke test was skipped. Only apply if_changed on other branches.

The health check wait is shorter than the sleep it replaced, so a
crash-looping container was more likely to be seen as running. Fail the
test if any container has restarted.

Amp-Thread-ID: https://ampcode.com/threads/T-01a1c731-7931-7091-9b5e-664cc2379c79
Co-authored-by: Amp <amp@ampcode.com>
The Buildkite pipeline's default branch is still "master", so
pipeline.default_branch never matched a build on main.

Amp-Thread-ID: https://ampcode.com/threads/T-01a1c731-7931-7091-9b5e-664cc2379c79
Co-authored-by: Amp <amp@ampcode.com>
marcleblanc2 and others added 2 commits November 10, 2026 16:19
…ale VMs

A build cancelled while GCP was still creating the VM leaked it, because
Vagrant only records the VM once the creation has finished, so the cleanup
found nothing to delete. The VM now carries its Buildkite job ID as a label,
and the cleanup deletes by that label.

As a backstop for jobs which die before their cleanup runs, every job deletes
labelled VMs older than an hour. The step times out after 30 minutes, so no
running job owns a VM that old.

Amp-Thread-ID: https://ampcode.com/threads/T-01a1c731-7931-7091-9b5e-664cc2379c79
Co-authored-by: Amp <amp@ampcode.com>
Vagrant creates the boot disk before the VM, and the disk carries no labels.
A build cancelled between the two left the disk behind, and the label lookup
from the previous commit could not find it. sourcegraph-ci holds three such
disks, from September.

The VM and its disk are now named docker-test-job-<Buildkite job ID>. The
cleanup and the stale sweep delete VMs by that name, and disks by that name
which no VM uses. This replaces the label.

Amp-Thread-ID: https://ampcode.com/threads/T-01a1c731-7931-7091-9b5e-664cc2379c79
Co-authored-by: Amp <amp@ampcode.com>
@marcleblanc2

Copy link
Copy Markdown
Contributor Author

Closing in favor of smaller PRs in the stack at https://github.com/sourcegraph/deploy-sourcegraph-docker/stack/1491: #1484 skips the smoke test on branches which only change Markdown files, and #1487 pulls images in parallel and waits for health checks instead of sleeping. The Vagrant speed-ups here are not needed, because #1488 removes Vagrant. The branch stays.

@marcleblanc2
marcleblanc2 deleted the speed-up-ci-smoke-test branch November 11, 2026 23:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant