Skip to content

[BUGFIX] Skip class loading info dump in Composer mode#731

Merged
sbuerk merged 1 commit into
9from
bugfix/725-skip-class-loading-dump-composer-mode-9
Jul 23, 2026
Merged

[BUGFIX] Skip class loading info dump in Composer mode#731
sbuerk merged 1 commit into
9from
bugfix/725-skip-class-loading-dump-composer-mode-9

Conversation

@sbuerk

@sbuerk sbuerk commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

Backport of #730 to branch 9. Related: #725.

Clean cherry-pick of 6073033 — no adaptation needed, the code is identical on both branches.

Problem

Testbase::dumpClassLoadingInformation() is called unconditionally — also from
Resources/Core/Build/UnitTestsBootstrap.php, which runs in the scope of the outer
Composer installation
.

TYPO3 v14.3.1 changed where the classic-mode autoload information of the testing context is
written. ClassLoadingInformation::getClassLoadingInformationDirectory() now derives the
directory from Environment::getExtensionsPath(), and that resolves to
<projectRoot>/packages/ext in Composer mode:

v13.4 v14.3.1+
getExtensionsPath() (Composer mode) <public>/typo3conf/ext <project>/packages/ext
dump dir (testing context) <public>/typo3conf/autoload-tests/ <project>/packages/autoload-tests/

So every unit test run creates <projectRoot>/packages/autoload-tests/, colliding with the
directory many projects use for their own local extensions.

Accountable Core change: edfb03ae775 / 770c5383930 "[TASK] Allow public folder in classic
mode"
, forge #109470, Gerrit
93491 /
93799.

Why branch 9 matters most here

Branch 9 supports core v13 and v14 — it is the branch v14 users actually consume today,
so it is the branch where the bug is reachable in practice. The reporter of #725 hit it with
testing-framework 9.5.0 on TYPO3 14.3.4.

No core-version-aware code needed

The guard works unchanged on both cores this branch supports:

  • Environment::isComposerMode() exists unchanged since v9.
  • PackageManager::scanAvailablePackages() has the identical Composer-mode early return on
    v12, v13, v14 and main — verified against v13.4.33 and v14.3.5 sources.

So the dump was already a no-op in Composer mode on v13 (four empty files, 118/147/147/147
bytes); only the location regressed on v14.3.1, from gitignored build output to the project
root. Nothing can be lost by not writing them.

Functional tests are not affected

Caller Composer mode Dump
UnitTestsBootstrap.php (extension/project) TYPO3_COMPOSER_MODEtrue skipped (was empty anyway)
UnitTestsBootstrap.php (Core mono-repository) undefined → false unchanged
Testbase::setUpBasicTypo3Bootstrap() (all functional tests) hard-coded false unchanged

Test results

Verified with this exact guard applied to the vendored testing-framework 9.6.0 in two
extensions, PHP 8.2, sqlite. Baseline (unpatched) unit runs were done first on each core, so
the before/after is on the same project rather than inferred.

web-vision/deepltranslate-core — ships
three functional fixture extensions, the case that would break if the guard were wrong:

Core Suite Result
v13.4.33 -s unit (baseline) SUCCESS — no packages/, dump at .Build/Web/typo3conf/autoload-tests/
v13.4.33 -s unit (patched) SUCCESS (16 tests, 30 assertions) — no packages/
v13.4.33 -s functional (patched) SUCCESS (44 tests, 101 assertions)
v14.3.5 -s unit (baseline) SUCCESS — packages/autoload-tests/ created, four empty files
v14.3.5 -s unit (patched) SUCCESS (16 tests, 30 assertions) — no packages/
v14.3.5 -s functional (patched) SUCCESS (44 tests, 101 assertions)

Functional instances still receive the full classic-mode dump, including the fixture extension
and all Tests/ directories:

'WebVision\TestingFrameworkBackendUserHandlerReplacement\'
    => typo3conf/ext/deepltranslate_core/Tests/Functional/Fixtures/Extensions/
       testing_framework_backenduserhandler_replacement/Classes
'WebVision\Deepltranslate\Core\Tests\'   => typo3conf/ext/deepltranslate_core/Tests
'WebVision\Deepltranslate\Core\Testing\' => typo3conf/ext/deepltranslate_core/TestClasses
'WebVision\Deepl\Base\Tests\'            => typo3conf/ext/deepl_base/Tests

plus 100 class map entries.

web-vision/deepl-write:

Core Suite Result
v14.3.5 -s unit SUCCESS — no packages/ (before: created)
v14.3.5 -s functional SUCCESS (10 tests, 11 assertions)
v13.4.33 -s unit SUCCESS — no packages/
v13.4.33 -s functional SUCCESS (4 tests, 3 assertions)

TYPO3 Core mono-repository (main, v15-dev), PHP 8.4 — behaviour unchanged, mono-repo is
classic mode:

Suite Result
-s unit -- --filter GeneralUtilityTest SUCCESS (676 tests, 756 assertions), typo3conf/autoload-tests/ still written
-d sqlite -s functional -- typo3/sysext/core/Tests/Functional/Package/ SUCCESS (6 tests, 26 assertions)
-d sqlite -s functional -- typo3/sysext/extbase/Tests/Functional/Persistence/ SUCCESS (468 tests, 1671 assertions)

This branch's own gates, PHP 8.2:

Gate Result
-s composerUpdate SUCCESS
-s cgl -n SUCCESS
-s lint SUCCESS
-s phpstan SUCCESS — no errors
-s unit SUCCESS — 124 tests, 329 assertions

Note for users

A packages/autoload-tests/ directory left behind by an earlier test run has to be removed
manually once — this change only stops new ones from being created.

Testbase::dumpClassLoadingInformation() is called unconditionally, also
from the unit test bootstrap, which runs in the scope of the outer
Composer installation. TYPO3 v14.3.1 changed where the classic mode
autoload information of the testing context is written: the dump
directory is now derived from Environment::getExtensionsPath(), which
resolves to "<projectRoot>/packages/ext" in Composer mode. Unit test
runs therefore create "<projectRoot>/packages/autoload-tests/",
colliding with the directory many projects use for their own local
extensions.

That dump is a no-op in Composer mode anyway, because
PackageManager::scanAvailablePackages() bails out early there and
leaves UnitTestPackageManager without any registered package. The
generated files have always been empty in that case, on v13 as well -
only their location changed, from build output to the project root.

Skip the dump in Composer mode, mirroring the guard TYPO3 Core uses on
all of its own call sites. Functional tests are unaffected:
setUpBasicTypo3Bootstrap() forces Composer mode to false, so their
instances keep receiving the class loading information they need for
their fixture extensions. The Core mono repository keeps its current
behaviour for the same reason.

Note that a "packages/autoload-tests/" directory left behind by an
earlier test run has to be removed manually once.

Resolves: #725
Releases: main, 9
@sbuerk
sbuerk merged commit cdac90f into 9 Jul 23, 2026
8 checks passed
@sbuerk
sbuerk deleted the bugfix/725-skip-class-loading-dump-composer-mode-9 branch July 23, 2026 08:15
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.

1 participant