Skip to content

IBX-11939: Moved the baseline fixture import into its own bootstrapper hook - #57

Open
Steveb-p wants to merge 7 commits into
4.6from
feature/append-only-fixtures-4.6
Open

Steveb-p wants to merge 7 commits into
4.6from
feature/append-only-fixtures-4.6

Conversation

@Steveb-p

@Steveb-p Steveb-p commented Sep 20, 2026 •

Copy link
Copy Markdown
Collaborator
🎫 Issue IBX-11939

Related PRs:

Description:

The baseline repository content in test_data.yaml has a second source: on the Doctrine
Migrations install path, ibexa/core's ImportDataMigration inserts the same rows from its
import-data SQL. Both write the same primary keys, so importing the fixture on top of the
migration collides — the bootstrapper needs a way to leave it out.

My first attempt did that with a marker (BaseFixture) plus a skip_base_fixture option on
FixtureHook, and it doesn't hold up. The provider chain is a replacement mechanism — one
provider wins and decides what a package contributes — while the baseline is an "always",
independent of that choice. Putting the two in one list makes the baseline something a package
can lose by accident, in two ways. corporate-account composes it into its own output by
unwrapping with Fixture::load() and re-merging into an anonymous Fixture, so the marker is
gone before the hook ever sees it. And setting ibexa.test.fixture_files outranks the
kernel-method provider (100 vs 0), so it drops the baseline outright — nothing uses that
parameter yet, but it's the mechanism we want people to move to.

So the baseline is now its own hook. BaseFixtureHook reads DefaultFixtureProvider directly
and imports it at priority 950 — after the schema is in place, before the package fixtures
layered on top. load_base_fixture defaults to true; the Doctrine Migrations bootstrap sets
it to false. FixtureHook and the chain now mean package fixtures only, and
IbexaTestKernel::getFixtures() stops yielding the baseline — it's deprecated and BC-only, and
the hook covers every kernel regardless of what that method does.

Nothing breaks in the interim for packages that still yield from $this->defaultProvider: the
baseline just gets imported twice, which truncates and reinserts the same rows. Wasteful, not
wrong. Those yield from lines can come out per package afterwards.

One case does need a change though — corporate-account merges its fixtures into a single
synthetic one precisely because FixtureImporter truncates before inserting, and
test_company.yaml writes into six tables the baseline also populates
(ezcontentobject, _attribute, _link, _name, _tree, _version). Once the baseline is a
separate import() call, that has to become an AppendOnlyFixture — which is the matching piece
in ibexa/core#785. I checked the other packages' fixture tables; cart, order-management and
discounts are fully disjoint from the baseline, so they're unaffected.

One more thing fell out of this, unrelated to the hook split itself. test_data.yaml had language
ID 2 as eng-US and ID 8 as eng-GB, while ibexa/core's cleandata.sql - and the
ImportDataMigration generated from it - gives ID 2 eng-GB, and doesn't define ID 8 at all.
Nothing ever loaded both datasets into the same database, so the two mappings never had to agree
with each other. Once the baseline comes from the install data and the package fixtures are layered
on top of it, they do.

So I swapped them: ID 2 is eng-GB as in a real install, and eng-US moves to ID 8. It's a large
diff (286 lines each way) because every serialized locale string in the file has to follow the ID
it's attached to, but it's a pure string swap - the IDs and the language masks are untouched, so
content stays in the same rows with the same masks.

…r hook

The baseline repository content (DefaultFixtureProvider's test_data.yaml) has a second
source: on the Doctrine Migrations install path, ibexa/core's ImportDataMigration inserts
the same rows from its import-data SQL. Importing the fixture on top of that collides on
the same primary keys, so the bootstrapper needs a way to leave it out.

Routing that through FixtureHook's provider chain doesn't hold up. The chain is a
replacement mechanism - one provider wins and decides what a package contributes - while
the baseline is an "always", independent of that choice. Two ways it gets lost: a provider
composing the baseline into its own output can dissolve it (corporate-account unwraps via
Fixture::load() and re-merges into an anonymous Fixture), and setting
ibexa.test.fixture_files outranks the kernel-method provider and drops it outright.

The baseline is now imported by BaseFixtureHook (priority 950, between the schema hooks and
FixtureHook), reading DefaultFixtureProvider directly. Its load_base_fixture option defaults
to true; the Doctrine Migrations bootstrap sets it to false. FixtureHook and the chain now
cover package fixtures only, and IbexaTestKernel::getFixtures() no longer yields the
baseline - it is deprecated and BC-only, and the hook covers every kernel regardless.

Pairs with ibexa/core's AppendOnlyFixture, which a package fixture needs when it writes into
tables the baseline already populates - otherwise FixtureImporter truncates those tables and
takes the baseline's rows with it. Of the packages checked, only corporate-account overlaps.
@Steveb-p
Steveb-p force-pushed the feature/append-only-fixtures-4.6 branch from a0b0cac to 5a38725 Compare September 21, 2026 09:21
@Steveb-p Steveb-p changed the title IBX-11939: Made the baseline fixture skippable for the Doctrine Migrations install path IBX-11939: Moved the baseline fixture import into its own bootstrapper hook Sep 21, 2026
IbexaTestCore::loadFixtures() imports whatever getFixtures() yields, with no hooks
involved, so emptying IbexaTestKernel::getFixtures() left that path with no baseline at
all. IbexaTestCore now supplies it - but only when the kernel is this package's
IbexaTestKernel, since any other IbexaTestKernelInterface implementation carries a
baseline of its own and would end up importing two.

Also made BaseFixtureHookTest's assertion tier-portable (it named ezcontentobject, which
does not exist at 5.0+) and dropped a redundant explicit service argument that autowiring
already resolves.
@Steveb-p
Steveb-p force-pushed the feature/append-only-fixtures-4.6 branch from 010b635 to 4e15e5c Compare September 21, 2026 13:37
A test case that installs the schema or imports fixtures in setUp() cannot be wrapped in
a transaction, so DAMADoctrineTestBundle - and per-test rollback generally - is off the
table for any suite that does it. The Bootstrapper already does both once per run via
DatabaseSchemaHook, BaseFixtureHook and FixtureHook, which is what makes transactional
tests possible.

Deprecated as of 4.6.31, for removal in 6.0:

  IbexaTestCoreInterface / IbexaTestCore  loadSchema(), getSchemaFiles(),
                                          loadFixtures(), getFixtures()
  IbexaTestKernel                         getSchemaFiles(), getFixtures()

The kernel pair covers the declaration side: fixtures belong in the
ibexa.test.fixture_files parameter or a tagged FixtureProviderInterface, and schema files
are not consulted at all under the Bootstrapper, which builds the schema from the
SchemaBuilderEvent instead. IbexaTestKernel::getFixtures() already carried an ad-hoc tag;
it is reworded to the same form as the rest.

Annotations only, in the format from PHP Conventions: Deprecation standards - no
behaviour change, and no trigger_deprecation() yet.
@Steveb-p
Steveb-p force-pushed the feature/append-only-fixtures-4.6 branch from 4e15e5c to 51db9dc Compare September 21, 2026 16:01
@Steveb-p
Steveb-p marked this pull request as ready for review September 23, 2026 14:19
@Steveb-p
Steveb-p requested a review from a team September 23, 2026 14:28
@ibexa-workflow-automation-1
ibexa-workflow-automation-1 Bot requested review from ViniTou, alongosz, barw4, bnowak, ciastektk, mikadamczyk and wiewiurdp and removed request for a team September 23, 2026 14:28
Comment thread src/contracts/IbexaTestCore.php Outdated
}

/**
* @deprecated 4.6.31 The "IbexaTestCore::loadSchema()" method is deprecated, will be removed in

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ATM 4.6.33, but given we don't release test-core, not sure if that makes sense either.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Changed to 4.6.33 across the whole PR.

…nstall

test_data.yaml gave language ID 2 the locale eng-US, while ibexa/core's
cleandata.sql - and the ImportDataMigration derived from it - gives ID 2
eng-GB. Nothing loaded both datasets into one database, so the contradiction
was invisible until the Doctrine Migrations install path started seeding the
test database from the install baseline.

Swaps the locales on IDs 2 and 8, so ID 2 is eng-GB as in a real install and
eng-US moves to ID 8. Language masks are untouched - the IDs keep their bit
values, only the locale each one maps to changes - so existing content stays
in the same rows and the same masks.
@Steveb-p
Steveb-p requested a review from alongosz September 24, 2026 09:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants