tests: an UpgradeFromPreviousReleaseIT boots the build on a deployment the previous release wrote (#7641) - #7685
Merged
delchev merged 1 commit intoOct 5, 2026
Conversation
…t the previous release wrote (eclipse-dirigible#7641) Every IT booted on an empty database, so nothing exercised an upgrade - yet eclipse-dirigible#7008, eclipse-dirigible#7370, eclipse-dirigible#7435, eclipse-dirigible#7597 and eclipse-dirigible#7049 were all failures only an existing database shows, each found on a user's instance. UpgradeFromPreviousReleaseIT runs the release named in tests/UPGRADE_FROM (14.74.0) as its published image on a Testcontainers PostgreSQL and drives it over HTTP: an intent project is generated and published, takes rows in every entity, parks one process instance per ticket on a user task, and a 5-second schedule fires. The release is stopped with SIGTERM and a grace period and its repository folder copied out (not bind-mounted: the image runs as root). The build under test then boots in-process on that database and folder with DIRIGIBLE_READINESS_REQUIRE_CLEAN_BOOT, and must accept traffic, leave no artefact failed, record every PostgreSQL changeset of its system changelog, keep every row and the running instances, and fire the job and start the process again for a new ticket. The datasources the previous release recorded are readdressed between the two phases: the container reaches the database by its network alias and the test JVM by the mapped port, and a datasource keeps the URL resolved when its file was parsed - which an unchanged file never is again. The helper lives in tests-framework (framework.upgrade). The IT is tagged `upgrade`: the api shards (build.yml, nightly.yml) and the PR gate exclude it, and a dedicated upgrade-test job runs it nightly and in release.yml, where release-docker-images now needs it. The release job writes the version it released into tests/UPGRADE_FROM in its development commit. Verified: green locally against 14.74.0 (66 s after the previous-release phase); red with Customer's name column renamed in the copied project (Name null after the upgrade); tag selection by JUnit dry run (upgrade: 1 class; api shard and PR gate: the IT excluded); tests-framework unit tests; formatter:validate with the cache wiped; release javadoc on tests-framework. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Cause
Every IT in
tests/tests-integrationsboots on an empty database, so nothing exercised an upgrade. #7008, #7370, #7435, #7597 and #7049 were all failures that only an existing database shows, and each was found on a user's instance, not in CI.Change
UpgradeFromPreviousReleaseIT(tests-integrations,@Tag("upgrade")) has two phases.The previous release writes a deployment. The release named in
tests/UPGRADE_FROM(14.74.0) runs as its publisheddirigiblelabs/dirigibleimage on a Testcontainers PostgreSQL. The test drives it over HTTP, the way the IDE does:UpgradeFromPreviousReleaseIT/app.intent) is generated and published;TicketReviewprocess instance per ticket on a user task;The release is then stopped like an orchestrator stops it (SIGTERM plus a 60 s grace period), and its repository folder is copied out of the container. It isn't bind-mounted, because the image runs as root and the test JVM couldn't write the files on a Linux runner.
The build under test boots in-process on that database and folder, with the readiness bridge and
DIRIGIBLE_READINESS_REQUIRE_CLEAN_BOOT=true. It must:isCleanBoot()true;dbmsfilters are honoured);The previous release is driven by a new helper in
tests-framework, packageframework.upgrade:PreviousReleaseresolves the tag (the system propertydirigible.upgrade.fromoverrides the file);PreviousReleaseEnvironmentruns the containers, does the graceful stop and copies the repository;PreviousReleaseClientmakes the HTTP calls.The existing in-process helpers (
ProjectDeployer,BaseIntentTestProject/ Selenide) can't target a release in a container, which is why the issue'sBaseIntentTestProjectisn't used.CI:
apishards inbuild.ymlandnightly.yml(both database legs) and the PR gate excludeupgrade. Dry runs confirm it:upgradeselects 1 class; theapiexpression (135 classes) and the PR gate (160) don't include the IT.upgrade-testjob runs-Dit.groups=upgradenightly and inrelease.yml, whererelease-docker-imagesnow hasneeds: upgrade-test, so the release images are pushed only if the upgrade passes. It needs Docker but no database service.tests/UPGRADE_FROMin its "for development" commit. The release commit itself is still tested from N-1, and master from N afterwards.ci.mddocuments the tag and the job.One thing the test environment needed, and a finding behind it
The two phases reach the same PostgreSQL by two names: the container uses its network alias
postgres:5432, the test JVM uses the mapped port. A datasource keeps the URL that was resolved when its file was parsed (DataSourcesSynchronizer→Configuration.configureObject, stored inDIRIGIBLE_DATA_SOURCES), and an unchanged file is never parsed again. So the build under test first tried to connect topostgresand failed. The IT therefore rewrites the recorded URLs between the phases (readdressRecordedDataSources, which fails if it rewrites nothing). A real deployment keeps its database address across an upgrade, so this doesn't weaken the test.The behaviour behind it is worth a separate issue, and I haven't changed it here: on an existing deployment, a changed
DIRIGIBLE_DATASOURCE_DEFAULT_URLdoesn't take effect, because the resolved URL persisted by an earlier boot wins.Verified
14.74.0: 66 s after the previous-release phase, about 2.5 min in total including that release's boot.[customers] expected: [{"Id"=1.0, "Name"="Acme"}] but was: [{"Id"=1.0, "Name"=null}]. After the edit was reverted, the file is byte-identical to the green version.tests-frameworkunit tests: 7 green, including 3 newPreviousReleaseTestcases for theUPGRADE_FROMlookup.mvn -T 1C formatter:validatewith the cache wiped: BUILD SUCCESS. The release javadoc build ontests-framework: BUILD SUCCESS.Not verified
Fixes #7641
🤖 Generated with Claude Code