Skip to content

Commit 78f495a

Browse files
committed
Merge branch '2.3.x' into fix/php-version-id-narrowing-below-configured
2 parents c56d8f0 + 5fb9346 commit 78f495a

79 files changed

Lines changed: 9890 additions & 893 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/e2e-tests.yml‎

Lines changed: 197 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2037,19 +2037,20 @@ jobs:
20372037
../bashunit assert not_contains 'Ds\Seq' "$OUTPUT"
20382038
- script: |
20392039
cd e2e/bug-15407
2040-
XDEBUG_HANDLER_DEBUG=1 ../../bin/phpstan analyse --no-progress 2>&1 | tee -a output.txt
2041-
../bashunit assert file_contains output.txt "Process restarting"
2040+
../../bin/phpstan analyse --no-progress -vvv 2>&1 | tee -a output.txt
2041+
../bashunit assert file_contains output.txt "Restarting process: pcov (pcov.enabled=1)"
20422042
coverage: "pcov"
20432043
- script: |
20442044
cd e2e/bug-15407
2045-
XDEBUG_HANDLER_DEBUG=1 ../../bin/phpstan analyse --no-progress 2>&1 | tee -a output.txt
2046-
../bashunit assert file_contains output.txt "Process restarting"
2045+
../../bin/phpstan analyse --no-progress -vvv 2>&1 | tee -a output.txt
2046+
../bashunit assert file_contains output.txt "Restarting process: pcov (pcov.enabled=1)"
20472047
coverage: "pcov"
20482048
ini-values: "pcov.enabled=1"
20492049
- script: |
20502050
cd e2e/bug-15407
2051-
XDEBUG_HANDLER_DEBUG=1 ../../bin/phpstan analyse --no-progress 2>&1 | tee -a output.txt
2052-
../bashunit assert file_not_contains output.txt "Process restarting"
2051+
# the restart may still happen to activate OPcache, just not for pcov
2052+
../../bin/phpstan analyse --no-progress -vvv 2>&1 | tee -a output.txt
2053+
../bashunit assert file_not_contains output.txt "pcov (pcov.enabled"
20532054
coverage: "pcov"
20542055
ini-values: "pcov.enabled=0"
20552056
@@ -2117,8 +2118,8 @@ jobs:
21172118
run: make build-turbo
21182119

21192120
- name: "Load the turbo extension through php.ini"
2120-
# TurboProcessRestarter re-executes the process with the loaded php.ini
2121-
# to activate OPcache; an extension passed as -d would not survive that,
2121+
# the restart re-executes the process with the loaded ini files to
2122+
# activate OPcache; an extension passed as -d would not survive that,
21222123
# one from the ini scan dir is loaded again
21232124
run: |
21242125
echo "extension=$PWD/turbo-ext/phpstan_turbo.so" | sudo tee "$(php -r 'echo PHP_CONFIG_FILE_SCAN_DIR;')/99-phpstan-turbo.ini"
@@ -2246,8 +2247,8 @@ jobs:
22462247
make -j"$(nproc)"
22472248
22482249
- name: "Load both extensions through php.ini"
2249-
# TurboProcessRestarter re-executes the process with the loaded php.ini
2250-
# to activate OPcache; extensions passed as -d would not survive that,
2250+
# the restart re-executes the process with the loaded ini files to
2251+
# activate OPcache; extensions passed as -d would not survive that,
22512252
# ones from the ini scan dir are loaded again
22522253
run: |
22532254
printf 'extension=%s\nextension=%s\n' "$PWD/turbo-ext/phpstan_turbo.so" "$RUNNER_TEMP/forkunsafe/modules/forkunsafe.so" | sudo tee "$(php -r 'echo PHP_CONFIG_FILE_SCAN_DIR;')/99-phpstan-turbo.ini"
@@ -2281,3 +2282,189 @@ jobs:
22812282
echo "$OUTPUT"
22822283
../bashunit assert contains 'Mechanism: fork (pcntl_fork)' "$OUTPUT"
22832284
../bashunit assert contains '[OK] No errors' "$OUTPUT"
2285+
2286+
process-restart-e2e-tests:
2287+
name: "Process restart E2E tests"
2288+
runs-on: ${{ matrix.operating-system }}
2289+
timeout-minutes: 30
2290+
2291+
defaults:
2292+
run:
2293+
shell: bash
2294+
2295+
strategy:
2296+
fail-fast: false
2297+
matrix:
2298+
include:
2299+
# pcov armed: one restart, every process - the forked worker
2300+
# included, which no per-worker `-d` injection could reach - runs
2301+
# disarmed. pcov stays loaded: the rows disarm rather than unload,
2302+
# which keeps the extension's own symbols reflectable. setup-php
2303+
# loads OPcache dormant on CLI, so the same restart activates it in
2304+
# every Linux row
2305+
- operating-system: "ubuntu-latest"
2306+
coverage: "pcov"
2307+
extensions: ""
2308+
script: |
2309+
php ../../bin/phpstan analyse --no-progress
2310+
php check.php restarted-for=pcov,opcache pcov-armed=no pcov-loaded=yes opcache-cli-on=yes processes=2+ starts=2
2311+
2312+
# Windows has no pcntl_exec, so the restart runs as a child process
2313+
# whose exit code is passed on. OPcache is left alone there: the
2314+
# workers are spawned, and ProcessHelper activates it for each
2315+
- operating-system: "windows-latest"
2316+
coverage: "pcov"
2317+
extensions: ""
2318+
script: |
2319+
php ../../bin/phpstan analyse --no-progress
2320+
php check.php restarted-for=pcov pcov-armed=no processes=1+ starts=2
2321+
set +e
2322+
php ../../bin/phpstan analyse --no-progress --configuration failing.neon
2323+
EXIT_CODE=$?
2324+
set -e
2325+
if [ "$EXIT_CODE" != "1" ]; then
2326+
echo "FAIL: the restarted process' exit code was not passed on, got $EXIT_CODE"
2327+
exit 1
2328+
fi
2329+
2330+
# xdebug: one restart disarms it via xdebug.mode=off, and it stays
2331+
# loaded so xdebug_*() remains reflectable. No note about it being
2332+
# active either
2333+
- operating-system: "ubuntu-latest"
2334+
coverage: "xdebug"
2335+
extensions: ""
2336+
script: |
2337+
php ../../bin/phpstan analyse --no-progress 2>&1 | tee out.txt
2338+
if grep -q 'The Xdebug PHP extension is active, but' out.txt; then
2339+
echo "FAIL: xdebug survived the restart armed"
2340+
exit 1
2341+
fi
2342+
php check.php restarted-for=xdebug,opcache xdebug-armed=no xdebug-loaded=yes processes=2+ starts=2
2343+
2344+
# XDEBUG_MODE overrides xdebug.mode, so flagging the ini alone would
2345+
# be silently overridable - the row exports the env var too
2346+
- operating-system: "ubuntu-latest"
2347+
coverage: "xdebug"
2348+
extensions: ""
2349+
script: |
2350+
XDEBUG_MODE=develop,debug php ../../bin/phpstan analyse --no-progress
2351+
php check.php restarted-for=xdebug,opcache xdebug-armed=no xdebug-loaded=yes processes=2+ starts=2
2352+
2353+
# --xdebug keeps xdebug armed and does not restart for it - only for
2354+
# OPcache
2355+
- operating-system: "ubuntu-latest"
2356+
coverage: "xdebug"
2357+
extensions: ""
2358+
script: |
2359+
php ../../bin/phpstan analyse --no-progress --xdebug 2>&1 | tee out.txt
2360+
if ! grep -q 'enabled, and the Xdebug PHP extension is active' out.txt; then
2361+
echo "FAIL: --xdebug did not keep xdebug"
2362+
exit 1
2363+
fi
2364+
php check.php restarted-for=opcache xdebug-armed=yes processes=1+ starts=2
2365+
2366+
# xdebug and pcov together: one restart handles both. Both come in
2367+
# through `extensions` because setup-php's `coverage: xdebug` unloads
2368+
# pcov. xdebug is armed by its default mode, pcov on the command
2369+
# line - which also proves the composed ini carries runtime `-d`
2370+
# overrides over without reconstructing them from $argv
2371+
- operating-system: "ubuntu-latest"
2372+
coverage: ""
2373+
extensions: "xdebug, pcov"
2374+
script: |
2375+
php -d pcov.enabled=1 ../../bin/phpstan analyse --no-progress
2376+
php check.php restarted-for=xdebug,pcov,opcache pcov-armed=no xdebug-armed=no processes=2+ starts=2
2377+
2378+
# --xdebug with pcov armed: xdebug stays armed, pcov is still
2379+
# disarmed by the same restart - something xdebug-handler could never
2380+
# express
2381+
- operating-system: "ubuntu-latest"
2382+
coverage: ""
2383+
extensions: "xdebug, pcov"
2384+
script: |
2385+
php -d pcov.enabled=1 ../../bin/phpstan analyse --no-progress --xdebug
2386+
php check.php restarted-for=pcov,opcache pcov-armed=no xdebug-armed=yes processes=1+ starts=2
2387+
2388+
# uopz rewrites opcodes unless uopz.disable=1
2389+
- operating-system: "ubuntu-latest"
2390+
coverage: "none"
2391+
extensions: "uopz"
2392+
script: |
2393+
php ../../bin/phpstan analyse --no-progress
2394+
php check.php restarted-for=uopz,opcache uopz-armed=no processes=2+ starts=2
2395+
2396+
# OPcache is dormant on CLI by default - the restart activates it,
2397+
# and the forked workers inherit the parent's warm opcode cache
2398+
- operating-system: "ubuntu-latest"
2399+
coverage: "none"
2400+
extensions: "opcache"
2401+
script: |
2402+
php -d opcache.enable_cli=0 ../../bin/phpstan analyse --no-progress -vvv > out.txt 2>&1
2403+
cat out.txt
2404+
php check.php restarted-for=opcache opcache-cli-on=yes processes=2+ starts=2
2405+
if ! grep -qE 'Mechanism: +fork' out.txt; then
2406+
echo "FAIL: the workers were not forked under the activated OPcache"
2407+
exit 1
2408+
fi
2409+
2410+
# --debug restarts like any other run - it only makes the analysis
2411+
# serial, --xdebug is what keeps xdebug
2412+
- operating-system: "ubuntu-latest"
2413+
coverage: "pcov"
2414+
extensions: ""
2415+
script: |
2416+
php ../../bin/phpstan analyse --no-progress --debug
2417+
php check.php restarted-for=pcov,opcache pcov-armed=no processes=1 starts=2
2418+
2419+
# diagnose never restarts either, it reports what a run would do
2420+
- operating-system: "ubuntu-latest"
2421+
coverage: "pcov"
2422+
extensions: ""
2423+
script: |
2424+
php ../../bin/phpstan diagnose 2>&1 | tee out.txt
2425+
if ! grep -qE 'Restart if started now: +yes - pcov' out.txt; then
2426+
echo "FAIL: diagnose did not report the restart it would perform"
2427+
exit 1
2428+
fi
2429+
2430+
steps:
2431+
- name: Harden the runner (Audit all outbound calls)
2432+
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
2433+
with:
2434+
egress-policy: audit
2435+
2436+
- name: "Checkout"
2437+
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
2438+
with:
2439+
persist-credentials: false
2440+
2441+
- name: "Install PHP"
2442+
uses: "shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962" # 2.40.0
2443+
with:
2444+
coverage: ${{ matrix.coverage }}
2445+
php-version: "8.2"
2446+
extensions: ${{ matrix.extensions }}
2447+
2448+
- uses: "ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda" # v4.0.0
2449+
2450+
- name: "Test"
2451+
working-directory: "e2e/restart-manager"
2452+
env:
2453+
SCRIPT: ${{ matrix.script }}
2454+
# Symfony wraps its notes to the terminal width and prefixes wrapped
2455+
# lines with "!", which can split a phrase in a way no post-processing
2456+
# rejoins - and would make the negative assertions pass vacuously
2457+
COLUMNS: "400"
2458+
run: |
2459+
# count every start of the main process, the one before the restart
2460+
# included - which only an ini-level hook sees
2461+
LINE=$(php -r 'echo "auto_prepend_file=\"", getcwd(), DIRECTORY_SEPARATOR, "start-log.php\"";')
2462+
INI=$(php -r 'echo php_ini_loaded_file();')
2463+
if [ "$RUNNER_OS" = "Windows" ]; then
2464+
echo "$LINE" >> "$INI"
2465+
else
2466+
echo "$LINE" | sudo tee -a "$INI" > /dev/null
2467+
fi
2468+
php ../../bin/phpstan clear-result-cache
2469+
rm -f probe.log starts.log
2470+
eval "$SCRIPT"

0 commit comments

Comments
 (0)