Skip to content

[BUGFIX] Drop only bootstrap-opened output buffers#733

Merged
sbuerk merged 1 commit into
mainfrom
bugfix/732-output-buffer-level-aware
Jul 23, 2026
Merged

[BUGFIX] Drop only bootstrap-opened output buffers#733
sbuerk merged 1 commit into
mainfrom
bugfix/732-output-buffer-level-aware

Conversation

@sbuerk

@sbuerk sbuerk commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

TYPO3 v15 removes the implicit output buffer that Bootstrap::init() opened as
its very first action. Two places in this package compensated for that buffer
with an unconditional ob_end_clean():

  • Testbase::setUpBasicTypo3Bootstrap() — called from both branches of
    FunctionalTestCase::setUp(), i.e. once per test
  • FunctionalTestCase::executeFrontendSubRequest() — the "somewhere an
    ob_start() is called in frontend" of that comment is the
    Bootstrap::init() call a few lines above

Without the bootstrap buffer these calls close phpunit's own output buffer
instead, and phpunit reports every functional test as risky with
Test code or tested code closed output buffers other than its own.

Both places now remember ob_get_level() before Bootstrap::init() and unwind
only the buffers opened above that level. Deleting the calls outright was not an
option: branch main supports typo3/cms-core: 14.*.*@dev || 15.*.*@dev, and
TYPO3 v14 Bootstrap::init() still opens the buffer — a plain removal would
flip the failure mode on v14 to …did not close its own output buffers. The
while loop additionally guards the frontend sub request against stray buffers
left open by extension code, which is what the old "work around that for now"
comment was really about.

Reproduction

TYPO3 Core main with https://review.typo3.org/c/Packages/TYPO3.CMS/+/94863
cherry-picked, before this change:

Build/Scripts/runTests.sh -s functional -d sqlite typo3/sysext/core/Tests/Functional/Database/
→ Tests: 376, Assertions: 1309, Skipped: 34, Risky: 376

Build/Scripts/runTests.sh -s functional -d sqlite typo3/sysext/frontend/Tests/Functional/Rendering/TypeRenderingTest.php
→ Tests: 9, Assertions: 9, Risky: 9

Core CI for that change fails in all functional jobs (sqlite 3/3, mariadb 6/6,
postgres 10/10) while unit, phpstan, cgl, lint, integration various,
documentation rendering and the playwright e2e jobs stay green.

Core test runs with this change

vendor/typo3/testing-framework replaced by this branch.

TYPO3 v15 — Core main @ 3c6390b797a + Gerrit 94863/1 cherry-picked,
PHP 8.5, sqlite:

runTests.sh -s functional -d sqlite \
  typo3/sysext/core/Tests/Functional/Database/ \
  typo3/sysext/frontend/Tests/Functional/Rendering/TypeRenderingTest.php \
  typo3/sysext/frontend/Tests/Functional/Rendering/UriPrefixRenderingTest.php
→ Tests: 389, Assertions: 1338, Skipped: 34 — SUCCESS (0 risky)

runTests.sh -s functional -d sqlite typo3/sysext/core/Tests/Functional/
→ Tests: 4224, Assertions: 56298, Skipped: 36 — SUCCESS (0 risky)

TYPO3 v14 — Core 14 @ dd5735757cb (bootstrap does open the buffer),
PHP 8.2, sqlite:

runTests.sh -s functional -d sqlite \
  typo3/sysext/core/Tests/Functional/Database/ \
  typo3/sysext/frontend/Tests/Functional/Rendering/TypeRenderingTest.php \
  typo3/sysext/frontend/Tests/Functional/Rendering/UriPrefixRenderingTest.php
→ Tests: 384, Assertions: 1317, Skipped: 34 — SUCCESS (0 risky)

Package quality gates

Build/Scripts/runTests.sh in this repo, PHP 8.2 (default):

Gate Result
-s composerUpdate SUCCESS
-s cgl -n SUCCESS (0 of 64 files to fix)
-s lint SUCCESS
-s phpstan SUCCESS (no errors)
-s unit SUCCESS (127 tests, 337 assertions)

Notes

No backport needed: branches 9/8/7 do not support TYPO3 v15, so their
bootstrap always opens the buffer and the current unconditional ob_end_clean()
stays correct there.

Resolves: #732
Related: https://forge.typo3.org/issues/110250
Related: https://review.typo3.org/c/Packages/TYPO3.CMS/+/94863
Releases: main

TYPO3 v15 removes the implicit output buffer that Bootstrap::init()
opened as its very first action. Two places compensated for that
buffer with an unconditional ob_end_clean(): setUpBasicTypo3Bootstrap()
in Testbase and executeFrontendSubRequest() in FunctionalTestCase.

Without the bootstrap buffer, these calls close phpunit's own output
buffer instead. phpunit then reports every functional test as risky
with "Test code or tested code closed output buffers other than its
own", which fails all functional jobs of the core test suite.

Both places now remember ob_get_level() before Bootstrap::init() and
unwind only the buffers opened above that level. This keeps working
with TYPO3 v14, where the bootstrap still opens a buffer, and it
additionally guards the frontend sub request against stray buffers
left open by extension code.

Resolves: #732
Related: https://forge.typo3.org/issues/110250
Related: https://review.typo3.org/c/Packages/TYPO3.CMS/+/94863
Releases: main
@sbuerk
sbuerk merged commit 9724b52 into main Jul 23, 2026
8 checks passed
@sbuerk
sbuerk deleted the bugfix/732-output-buffer-level-aware branch July 23, 2026 17:13
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.

Functional tests risky when TYPO3 v15 Bootstrap no longer opens an output buffer

2 participants