Skip to content

ci: matrix tests by adapter as well as PHP version#78

Merged
abnegate merged 1 commit into
mainfrom
ci/adapter-matrix
Jun 23, 2026
Merged

ci: matrix tests by adapter as well as PHP version#78
abnegate merged 1 commit into
mainfrom
ci/adapter-matrix

Conversation

@abnegate

Copy link
Copy Markdown
Member

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

  • Isolation — a failure points at one adapter, not "the suite".
  • No cross-contamination — the slow/flaky redis-cluster only spins up for the cluster job, so it can't flake Memory/Filesystem/etc.
  • Faster jobs — most adapters need no service (Memory, None, Filesystem, Pool, CircuitBreaker, Telemetry); they no longer wait on the full stack.

Changes

  • phpunit.xml — per-adapter testsuites. The redis suite is directory-based, so it also covers MultiplexingTest (and any future redis-only test) while excluding RedisClusterTest, 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 (cache-tests:<php>) for build-once / load-many.
    • Fix the phpunit.xml bind-mount path (/usr/code/usr/src/code).
    • Add redis-family and cluster healthchecks so --wait is reliable.
  • .github/workflows/test.yml — a build job builds + caches the per-PHP image once; unit and per-adapter adapter jobs load it and bring up only their own services via docker 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.4 locally and ran each service-backed suite with only its services up:

Suite Result
memory OK (8)
redis (RedisTest + Multiplexing, cluster excluded) OK (20)
sharding OK (9)
memcached OK (9)
unit OK (49)

--no-deps --wait confirmed to start only the named services. redis-cluster couldn't be exercised locally — its amd64-only image segfaults redis-cli under qemu on Apple Silicon — but the healthcheck command is the same redis-cli mechanism that the native redis/shard images pass, and CI runners are amd64.

Notes

  • Independent of feat(cache): Leasable primitive to close the cache-aside read-after-write race #75; once that merges, its LeasableTest lands under tests/Cache/E2E/Redis/ and is picked up by the directory-based redis suite automatically — no matrix edit needed.
  • The e2e aggregate testsuite is replaced by the granular per-adapter suites; running phpunit with no --testsuite still executes the full set once (no file overlaps).

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings June 23, 2026 11:10

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@greptile-apps

greptile-apps Bot commented Jun 23, 2026

Copy link
Copy Markdown

Greptile Summary

This 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 docker-compose.yml gains project-name pinning, a corrected volume path, and healthchecks for all Redis-family containers.

  • .github/workflows/test.yml: Adds a build job that builds and caches a Docker image per PHP version; unit and adapter jobs load that image and bring up only the services their suite requires via --no-deps --wait.
  • docker-compose.yml: Pins name: cache, adds image: tag for pre-built image loading, fixes the phpunit.xml bind-mount path (/usr/code/usr/src/code), and adds healthchecks for redis, redis-cluster, shardA, shardB, and shardC.
  • phpunit.xml: Replaces the single e2e testsuite with 11 per-adapter testsuites; the redis suite uses directory scanning (picking up MultiplexingTest and the already-present LeasableTest) while explicitly excluding RedisClusterTest.php.

Confidence Score: 5/5

Safe 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

Filename Overview
.github/workflows/test.yml Adds build/unit/adapter job matrix (PHP × adapter). Well-structured with image caching and per-adapter service bring-up. Note: job-level needs: build dependency couples all PHP-version test jobs to every build matrix combination.
docker-compose.yml Pins project name, adds image tag for pre-built loading, fixes phpunit.xml volume path, and adds healthchecks for redis, redis-cluster, and all three shards. hazelcast and memcached remain without healthchecks (addressed in prior review threads).
phpunit.xml Replaces the single e2e testsuite with 11 per-adapter testsuites; redis uses directory scanning with RedisClusterTest.php excluded, which also picks up the already-present LeasableTest.php correctly.

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 }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 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.

Comment thread docker-compose.yml
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>
@abnegate abnegate force-pushed the ci/adapter-matrix branch from 66dae9e to 130d90c Compare June 23, 2026 11:21
@abnegate abnegate merged commit f9741ca into main Jun 23, 2026
42 checks passed
@abnegate abnegate deleted the ci/adapter-matrix branch June 23, 2026 11:46
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.

2 participants