Skip to content

perf(tests): one Dirigible boot per class for eight multi-method HTTP ITs - #6703

Merged
delchev merged 1 commit into
masterfrom
perf/it-after-class-batch1
Aug 13, 2026
Merged

perf(tests): one Dirigible boot per class for eight multi-method HTTP ITs#6703
delchev merged 1 commit into
masterfrom
perf/it-after-class-batch1

Conversation

@delchev

@delchev delchev commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Problem

IntegrationTest carries @DirtiesContext(classMode = AFTER_EACH_TEST_METHOD), so a class with N test methods boots the full Dirigible runtime N times. Across the suite that is 275 boots for 116 classes — ~41 minutes of pure Spring startup per CI leg (measured on run 31679871168). Follow-up to #6702, which sharded the jobs; this shrinks the biggest shard's actual compute.

Change

Override to @DirtiesContext(AFTER_CLASS) on the eight multi-method HTTP-level ITs whose methods already clean up after themselves — the pattern DatabaseFacadeIT has proven for a while (18 tests in 0.9s):

Class Methods CI baseline Local after (2 runs)
IntentEngineIT 42 337s 37s
NumberingSdkIT 8 131s 69s
SecurityIT 7 82s 21s
DataStoreIT 7 79s 20s
JavaEngineIT 5 77s 32s
CmsAccessControlIT 5 69s 23s
IntentConversationIT 5 67s 21s
EndpointAuthorizationIT 5 65s 21s

84 methods now cost 8 boots instead of 84 (~10 min off the api shard).

Where sharing the database across methods needed honesty, it was added rather than assumed:

  • SecurityUtil gains idempotent ensureUserInDefaultTenant variants — once the context survives the method, a repeated plain create violates the unique user constraint.
  • CmsAccessControlIT revokes its READ grant in a new @AfterEach — a leaked grant breaks the "open by default — no rule exists" premise the other tests start from — and its user setup becomes idempotent.
  • EndpointAuthorizationIT switches its repeated per-method user creation to the idempotent variant.

The remaining six classes keep only the annotation: IntentEngineIT, JavaEngineIT, IntentConversationIT and NumberingSdkIT already have honest @AfterEach cleanup; DataStoreIT recreates its tables in @BeforeEach; SecurityIT is read-only (MockMvc + @WithMockUser). NumberingSdkIT's assertions were audited for counter persistence: they are all relative (b == a+1), explicitly seeded, or use partition names unique to their method — consistent with the engine's own "counters are never reset" contract.

Deliberately NOT converted (candidates for a later batch, each needs its own analysis): LocalNativeAppLifecycleIT (OS process lifecycle), EnabledMultitenantModeIT (tenant provisioning), and the UI classes.

Verification

  • Two consecutive full runs of the converted batch (fresh target/dirigible each): 84/84 green, ~4:20 per run (the repeatability check the SecurityIT/System changelog: per-changeset MARK_RAN guards fix the SecurityIT smoke flake #6661 lesson calls for — leaked state shows up on the second run).
  • mvn formatter:validate green on both modules; mvn -P release javadoc check green on tests-framework (new public methods carry Javadoc).

🤖 Generated with Claude Code

… ITs

IntegrationTest dirties the Spring context AFTER_EACH_TEST_METHOD, so a
class with N methods boots the full runtime N times (~10-30s each).
Override to AFTER_CLASS on the multi-method HTTP-level ITs whose methods
already clean up after themselves - the pattern DatabaseFacadeIT has
proven for a while (18 tests in 0.9s):

  IntentEngineIT (42), NumberingSdkIT (8), SecurityIT (7), DataStoreIT
  (7), JavaEngineIT (5), CmsAccessControlIT (5), IntentConversationIT
  (5), EndpointAuthorizationIT (5)

84 methods now cost 8 boots instead of 84. Measured on the CI baseline
these classes took 907s of the api shard; two consecutive local runs of
the converted batch complete in ~4:20 with all 84 tests green.

Where sharing the database across methods needed honesty, it was added
rather than assumed: SecurityUtil gains idempotent ensureUserInDefault-
Tenant variants (a repeated plain create violates the unique user
constraint once the context survives the method), CmsAccessControlIT
revokes its READ grant after each test (a leaked grant breaks the
'open by default' premise the other tests start from), and
EndpointAuthorizationIT switches its repeated per-method user creation
to the idempotent variant.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@delchev
delchev merged commit ea7bfd3 into master Aug 13, 2026
10 checks passed
@delchev
delchev deleted the perf/it-after-class-batch1 branch August 13, 2026 12:34
delchev added a commit that referenced this pull request Aug 13, 2026
#6708)

Batch 2 of the AFTER_CLASS conversion (#6703 was batch 1): override
@DirtiesContext to AFTER_CLASS on the remaining multi-method IT classes
whose methods are read-only or clean up after themselves - audited
class-by-class for shared-database honesty. 60 test methods now cost 22
boots instead of 60, trimming both the api and ui CI shards.

Converted as-is (18): MonitoringPerspectiveIT, IntentBuilderShellIT,
MonitoringShellIT, DatabaseShellIT, ShellSwitcherIT,
EnabledMultitenantModeIT, CsvProcessorIT, RepositoryExportIT,
CsvimReimportIT, DocumentsApiIT, JavaBpmnIT, JavaCamelIT,
PerspectiveGroupAggregationIT, JavaCompilationProblemsIT, PrintRenderIT,
ArtefactStatusEndpointIT, BpmnModelApiIT, TenantConfigurationIT.

Converted with a state-honesty fix (4):
- RestTransactionsIT: new @AfterEach drops TESTTABLE and deletes the
  committed test user - two methods otherwise collide on both.
- IntentCrossModelScheduleSourceIT: cleanup force-syncs so the DELETE
  branch unschedules the published 5-second cron job, and the unpublish
  cleanup asserts a strict 2xx.
- SynchronizerCleanupRaceIT: the cleanup sync runs unconditionally - the
  publish-bypass test leaves a registered JavaFile whose source is gone,
  which otherwise makes every later rebuild defer.
- MessagingFacadeIT: the queue tests drain the now-persistent broker
  store before each method (FIFO and receive-timeout assertions need an
  empty queue).

Deliberately NOT converted, with cause: MultitenancyHarmoniaIT (the
fixture asserts absolute row counts and empty CMIS listings),
LocalNativeAppLifecycleIT (leaks live OS processes and duplicate
default-package FQNs between methods), SchemaExportImportIT (whole-
SystemDB export tuned to a pristine database).

Verified: two consecutive full runs of all 22 classes, fresh state each,
62/62 green both times.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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