ci: matrix tests by adapter as well as PHP version#78
Conversation
Greptile SummaryThis PR restructures the CI test suite from a single "one job per PHP version" approach to a PHP × adapter matrix, where each adapter runs in its own job and starts only the services it needs. The
Confidence Score: 5/5Safe to merge — all changes are to CI configuration and test orchestration only, with no impact on library source code. The restructuring is well-executed: image caching is correct, per-adapter service bring-up works as intended, healthchecks are added where they were missing for Redis containers, and the phpunit.xml testsuites cleanly map to the matrix entries. The one observation (job-level needs coupling) is a known GitHub Actions limitation that doesn't produce incorrect test results. No files require special attention; .github/workflows/test.yml has a minor design note about cross-matrix job dependencies. Important Files Changed
Reviews (2): Last reviewed commit: "ci: matrix tests by adapter as well as P..." | Re-trigger Greptile |
| - { name: CircuitBreaker, suite: circuitbreaker, services: '', wait: 0 } | ||
| - { name: Telemetry, suite: telemetry, services: '', wait: 0 } | ||
| - { name: Memcached, suite: memcached, services: 'memcached', wait: 3 } | ||
| - { name: Hazelcast, suite: hazelcast, services: 'hazelcast', wait: 30 } |
There was a problem hiding this comment.
Hazelcast readiness depends solely on a fixed
sleep
hazelcast has no healthcheck in docker-compose.yml, so --wait returns the moment the container transitions to "running" — before Hazelcast has actually bound its Memcache port. The 30-second sleep then becomes the real readiness gate. On a slow runner or under load this is fragile; on a fast runner the 30 s is always wasted. A TCP-probe healthcheck (CMD-SHELL nc -z localhost 11211 || exit 1) against the Memcache port would let --wait do the job reliably and remove the need for wait: 30 entirely.
Tests previously ran in one job per PHP version, spinning up every backing service at once and rerunning the whole suite. Add an adapter axis so each adapter runs in its own job across the PHP-version axis (PHP x adapter), starting only the services it needs. This isolates failures to a single adapter, cuts per-job startup, and keeps the slow/flaky redis-cluster out of unrelated jobs. - phpunit.xml: per-adapter testsuites. The redis suite is directory-based so it also covers MultiplexingTest (and any future redis-only test) while excluding the cluster, which needs a different service. - docker-compose.yml: pin the project name to `cache` (RedisClusterTest hardcodes the cache_database network), give the tests image a deterministic tag for build-once/load-many, fix the phpunit.xml bind-mount path, and add redis-family and cluster healthchecks so `--wait` is reliable. - test.yml: build and cache the per-PHP image once, then fan out unit and per-adapter jobs that load it and bring up only their own services. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
66dae9e to
130d90c
Compare
What
The test suite ran in one job per PHP version, spinning up every backing service at once and rerunning the whole suite. This adds an adapter axis so the matrix is now PHP × adapter — each adapter runs in its own job, across all PHP versions, starting only the services it needs.
This matches the adapter-matrix pattern used elsewhere in Utopia (e.g.
utopia-php/database).Why
redis-clusteronly spins up for the cluster job, so it can't flake Memory/Filesystem/etc.Changes
phpunit.xml— per-adapter testsuites. Theredissuite is directory-based, so it also coversMultiplexingTest(and any future redis-only test) while excludingRedisClusterTest, which needs a different service.docker-compose.ymlcache(RedisClusterTesthardcodes thecache_databasenetwork).cache-tests:<php>) for build-once / load-many.phpunit.xmlbind-mount path (/usr/code→/usr/src/code).redis-family and cluster healthchecks so--waitis reliable..github/workflows/test.yml— abuildjob builds + caches the per-PHP image once;unitand per-adapteradapterjobs load it and bring up only their own services viadocker compose up --no-deps --wait.Matrix
build(3) →unit(3) +adapter(11 adapters × 3 PHP = 33).fail-fast: false.Adapters: Memory, None, Filesystem, Pool, CircuitBreaker, Telemetry, Memcached, Hazelcast, Sharding, Redis, RedisCluster.
Verification
Built
cache-tests:8.4locally and ran each service-backed suite with only its services up:--no-deps --waitconfirmed to start only the named services.redis-clustercouldn't be exercised locally — its amd64-only image segfaultsredis-cliunder qemu on Apple Silicon — but the healthcheck command is the sameredis-climechanism that the nativeredis/shardimages pass, and CI runners are amd64.Notes
LeasableTestlands undertests/Cache/E2E/Redis/and is picked up by the directory-basedredissuite automatically — no matrix edit needed.e2eaggregate testsuite is replaced by the granular per-adapter suites; runningphpunitwith no--testsuitestill executes the full set once (no file overlaps).🤖 Generated with Claude Code