Skip to content

Commit 3eab1e9

Browse files
committed
feat - add script to run the tests in all the php versiones in docker
1 parent c3a3776 commit 3eab1e9

3 files changed

Lines changed: 231 additions & 0 deletions

File tree

llms.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,34 @@ Notes:
9090
- The **fixture harness** (`tests/run_all_tests.php`) is the primary “hard gate” for formatter behavior and should stay at `Broken:0`.
9191
- Under older runtimes (e.g. PHP 7.4), PHPUnit may report many **Skipped** tests due to runtime/dependency constraints; this is expected.
9292
- Prefer running PHPUnit with the default `php` (newer runtime) for full coverage, and use `php74 tests/run_all_tests.php` as the compatibility proxy.
93+
### 3) Docker matrix (multi-PHP testing)
9394

95+
Run tests across multiple PHP versions (5.6 → 8.5) in Docker containers:
96+
97+
```bash
98+
# Run all versions (default: 5.6 7.0 7.1 7.2 7.3 7.4 8.0 8.1 8.2 8.3 8.5)
99+
./tests/docker-test-matrix.sh
100+
101+
# Run specific versions
102+
PHP_VERSIONS="5.6 7.4 8.2" ./tests/docker-test-matrix.sh
103+
104+
# Disable PHPUnit (only run fixture tests)
105+
RUN_PHPUNIT=0 ./tests/docker-test-matrix.sh
106+
```
107+
108+
Scripts:
109+
- `tests/docker-test-matrix.sh` — Wrapper that iterates PHP versions and runs Docker containers.
110+
- `tests/docker-test-matrix-inner.sh` — Runs inside each container: executes `run_all_tests.php` and PHPUnit.
111+
112+
Behavior:
113+
- Stops at the first failing PHP version (fail-fast).
114+
- PHP 5.6 uses `phpunit-5.7.phar` directly (avoids Debian EOL apt issues).
115+
- PHP 7.3+ installs PHPUnit via Composer inside the container.
116+
- PHP 7.0–7.2 skips PHPUnit by default (set `RUN_PHPUNIT_LEGACY=1` to try).
117+
118+
Requirements:
119+
- Docker installed and running.
120+
- On macOS/Apple Silicon, images run with `--platform linux/amd64` (configurable via `DOCKER_PLATFORM`).
94121
## Creating a new fixture test (`.in`/`.out`)
95122

96123
1) Pick a new number

tests/docker-test-matrix-inner.sh

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
#!/bin/sh
2+
set -eu
3+
4+
mkdir -p /work
5+
# Copy repo into container FS (avoid modifying host); exclude vendor to keep it small.
6+
tar -C /src --exclude=vendor --exclude=.git -cf - . | tar -C /work -xf -
7+
cd /work
8+
9+
echo '--- php -v ---'
10+
php -v
11+
12+
echo '--- run_all_tests.php (tests/run_all_tests.php) ---'
13+
php tests/run_all_tests.php
14+
15+
echo '--- run_all_tests.php exit:' $?
16+
17+
php_mm="$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')"
18+
echo "--- PHP detected: ${php_mm} ---"
19+
20+
php_major="$(php -r 'echo PHP_MAJOR_VERSION;')"
21+
php_minor="$(php -r 'echo PHP_MINOR_VERSION;')"
22+
23+
if [ "$php_major" -eq 5 ] && [ "$php_minor" -eq 6 ]; then
24+
echo '--- phpunit (PHP 5.6, phpunit 5.7 phar) ---'
25+
26+
# Avoid Composer + system package installs on EOL Debian images.
27+
php -r "copy('https://phar.phpunit.de/phpunit-5.7.phar', '/tmp/phpunit.phar');" || {
28+
echo 'ERROR: failed to download phpunit-5.7.phar' >&2
29+
exit 1
30+
}
31+
32+
# Minimal phpunit.xml compatible with PHPUnit 5.x.
33+
cat > /tmp/phpunit.xml <<'XML'
34+
<?xml version="1.0" encoding="UTF-8"?>
35+
<phpunit colors="false" stopOnFailure="true">
36+
<testsuites>
37+
<testsuite name="Unit">
38+
<directory suffix="Test.php">/work/tests/Unit</directory>
39+
</testsuite>
40+
</testsuites>
41+
</phpunit>
42+
XML
43+
44+
php /tmp/phpunit.phar --version
45+
php /tmp/phpunit.phar --configuration /tmp/phpunit.xml
46+
exit 0
47+
fi
48+
49+
if [ "${RUN_PHPUNIT:-1}" != "1" ]; then
50+
echo '--- phpunit skipped (RUN_PHPUNIT!=1) ---'
51+
exit 0
52+
fi
53+
54+
# Helper: install composer.phar using PHP itself (no curl/wget requirement).
55+
install_composer() {
56+
url="$1"
57+
php -r "copy('${url}', '/tmp/composer.phar');" || return 1
58+
php /tmp/composer.phar --version >/dev/null 2>&1 || return 1
59+
}
60+
61+
# Best-effort: ensure unzip/git exist for composer installs (may fail on very old images).
62+
ensure_tools() {
63+
if command -v unzip >/dev/null 2>&1 && command -v git >/dev/null 2>&1; then
64+
return 0
65+
fi
66+
67+
echo '--- installing required tools (git, unzip) ---'
68+
69+
if command -v apk >/dev/null 2>&1; then
70+
apk add --no-cache git unzip ca-certificates
71+
elif command -v apt-get >/dev/null 2>&1; then
72+
export DEBIAN_FRONTEND=noninteractive
73+
74+
apt_update() {
75+
apt-get -o Acquire::Check-Valid-Until=false update
76+
}
77+
78+
fix_debian_eol_sources() {
79+
# Old PHP images (php:5.6/7.0/7.1/7.2) are often based on EOL Debian (e.g. stretch).
80+
# Switch to archive mirrors and disable Valid-Until checks.
81+
if [ -d /etc/apt ]; then
82+
printf '%s\n' \
83+
'Acquire::Check-Valid-Until "false";' \
84+
'Acquire::AllowInsecureRepositories "true";' \
85+
'Acquire::AllowDowngradeToInsecureRepositories "true";' \
86+
> /etc/apt/apt.conf.d/99phpfmt-eol 2>/dev/null || true
87+
88+
for f in /etc/apt/sources.list /etc/apt/sources.list.d/*.list; do
89+
[ -f "$f" ] || continue
90+
sed -i \
91+
-e 's|http://deb.debian.org/debian|http://archive.debian.org/debian|g' \
92+
-e 's|http://security.debian.org/debian-security|http://archive.debian.org/debian-security|g' \
93+
-e 's|http://security.debian.org|http://archive.debian.org/debian-security|g' \
94+
"$f" 2>/dev/null || true
95+
96+
# archive.debian.org does not provide *-updates suites consistently; disable them.
97+
sed -i \
98+
-e '/-updates/ s/^deb /# deb /' \
99+
-e '/-updates/ s/^deb-src /# deb-src /' \
100+
"$f" 2>/dev/null || true
101+
done
102+
fi
103+
}
104+
105+
if ! apt_update; then
106+
echo '--- apt-get update failed; trying archive.debian.org (EOL Debian) ---'
107+
fix_debian_eol_sources
108+
apt_update
109+
fi
110+
111+
apt-get install -y --no-install-recommends git unzip ca-certificates
112+
elif command -v yum >/dev/null 2>&1; then
113+
yum install -y git unzip ca-certificates
114+
else
115+
echo 'ERROR: no supported package manager found to install git/unzip (need git or unzip for Composer).' >&2
116+
exit 2
117+
fi
118+
119+
if ! command -v unzip >/dev/null 2>&1 && ! command -v git >/dev/null 2>&1; then
120+
echo 'ERROR: failed to install git/unzip; Composer will not be able to download dependencies.' >&2
121+
exit 2
122+
fi
123+
}
124+
125+
if [ "$php_major" -gt 7 ] || { [ "$php_major" -eq 7 ] && [ "$php_minor" -ge 3 ]; }; then
126+
echo '--- phpunit (root composer.json, phpunit ^9.6) ---'
127+
ensure_tools
128+
install_composer 'https://getcomposer.org/download/2.2.23/composer.phar'
129+
rm -f composer.*
130+
php /tmp/composer.phar require phpunit/phpunit
131+
./vendor/bin/phpunit
132+
exit 0
133+
fi
134+
135+
if [ "$php_major" -eq 7 ] && [ "$php_minor" -ge 0 ] && [ "$php_minor" -le 2 ]; then
136+
if [ "${RUN_PHPUNIT_LEGACY:-0}" = "1" ]; then
137+
echo '--- phpunit (tests/composer.json, phpunit ^6.5) ---'
138+
ensure_tools
139+
install_composer 'https://getcomposer.org/download/1.10.26/composer.phar'
140+
(cd tests && rm -f composer.* && php /tmp/composer.phar require phpunit/phpunit && ./vendor/bin/phpunit) || {
141+
if [ "${STRICT_PHPUNIT:-0}" = "1" ]; then
142+
echo 'ERROR: legacy phpunit failed' >&2
143+
exit 1
144+
fi
145+
echo 'WARN: legacy phpunit failed; continuing (set STRICT_PHPUNIT=1 to fail)' >&2
146+
}
147+
else
148+
echo '--- phpunit skipped on PHP 7.0-7.2 (set RUN_PHPUNIT_LEGACY=1 to try) ---'
149+
fi
150+
exit 0
151+
fi
152+
153+
echo '--- phpunit skipped on this PHP version ---'

tests/docker-test-matrix.sh

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5+
6+
# Usage examples:
7+
# PHP_VERSIONS="5.6 7.4 8.2" ./tests/docker-test-matrix.sh
8+
# DOCKER_PLATFORM=linux/amd64 ./tests/docker-test-matrix.sh
9+
10+
PHP_VERSIONS=${PHP_VERSIONS:-"5.6 7.0 7.1 7.2 7.3 7.4 8.0 8.1 8.2 8.3 8.4 8.5"}
11+
12+
# On macOS/Apple Silicon, old PHP images are often amd64-only.
13+
DOCKER_PLATFORM=${DOCKER_PLATFORM:-"linux/amd64"}
14+
15+
# Run phpunit on supported versions (>=7.3) by default.
16+
RUN_PHPUNIT=${RUN_PHPUNIT:-"1"}
17+
# Opt-in: try running phpunit on PHP 7.0-7.2 via tests/composer.json + Composer 1.
18+
RUN_PHPUNIT_LEGACY=${RUN_PHPUNIT_LEGACY:-"0"}
19+
# If set to 1, phpunit failures will fail the whole script.
20+
STRICT_PHPUNIT=${STRICT_PHPUNIT:-"0"}
21+
22+
if ! command -v docker >/dev/null 2>&1; then
23+
echo "ERROR: docker not found in PATH" >&2
24+
exit 2
25+
fi
26+
27+
run_one() {
28+
local ver="$1"
29+
local image="php:${ver}-cli"
30+
31+
echo ""
32+
echo "=== PHP ${ver} (${image}) ==="
33+
34+
docker run --rm \
35+
--platform "${DOCKER_PLATFORM}" \
36+
-v "${ROOT}:/src:ro" \
37+
-e RUN_PHPUNIT="${RUN_PHPUNIT}" \
38+
-e RUN_PHPUNIT_LEGACY="${RUN_PHPUNIT_LEGACY}" \
39+
-e STRICT_PHPUNIT="${STRICT_PHPUNIT}" \
40+
"${image}" sh /src/tests/docker-test-matrix-inner.sh
41+
}
42+
43+
for ver in ${PHP_VERSIONS}; do
44+
if ! run_one "${ver}"; then
45+
echo "FAIL: PHP ${ver} (stopping)" >&2
46+
exit 1
47+
fi
48+
echo "OK: PHP ${ver}"
49+
done
50+
51+
exit 0

0 commit comments

Comments
 (0)