Running in CI
A petri suite needs only go test: no service containers and no setup step.
Three things need attention: the build cache, memory, and timeouts.
Cache the build
The first build of a package that imports petri compiles kube-apiserver and
the controllers. That takes a few minutes on a CI runner. Later builds come
from Go's build cache, so keep that cache between runs. actions/setup-go does
this by default, keyed on go.sum.
name: Test
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v7
- uses: actions/setup-go@v7
with:
go-version-file: go.mod # caches the module and build caches
- run: go test -race -p 2 -timeout 20m ./...
Memory and -race
Each package that starts a control plane holds one in memory: about 300 MiB,
or 1 to 1.5 GiB under -race. Linking a test binary under -race takes about
3 GiB. Resource usage has the measurements
and explains why.
go test ./... builds and runs as many packages at once as there are CPUs,
which can run a small runner out of memory. To lower the load:
- run fewer packages at once with
-p 2or-p 1; - run fewer tests at once within a package with
-parallel N; - use
-racewhere it pays off. Keep it for packages with your own concurrent code, and consider dropping it for packages that only call the API.
If a job is killed without a test failure, or the log shows
signal: killed, the cause is almost always memory.
Timeouts
Go's default test timeout is 10 minutes per package. Compile time does not
count against it, but a large package of end-to-end tests under -race can
still get close. Set -timeout explicitly, as above.
petri's waits time out after 30 seconds by default. On a slow runner, give the
waits that need it a longer timeout with petri.WithTimeout, rather than
retrying whole tests.