Skip to content

Move test database properties to test resources - #3628

Open
duanemay wants to merge 5 commits into
developfrom
fix/test_props
Open

duanemay wants to merge 5 commits into
developfrom
fix/test_props

Conversation

@duanemay

@duanemay duanemay commented Sep 19, 2025 •

Copy link
Copy Markdown
Member

What

application-mysql.properties/application-postgresql.properties in server/src/main/resources shipped hardcoded database.username=root/database.password=changeme/a 127.0.0.1/local JDBC URL — these look like local test/dev fixtures, not production defaults, and end up packaged into the WAR. This moves those values into src/test/resources (kept for the test suite, which needs them), leaving only database.driverClassName in the packaged application-mysql.properties/application-postgresql.properties.

This is not a fix for an exploitable default: UAA falls back to the hsqldb profile with zero configuration (YamlServletProfileInitializer.applySpringProfiles), so these values are only ever read if an operator explicitly activates the mysql/postgresql profile. It's hygiene — don't ship plausible-looking credentials in the production artifact.

Follow-up fix included

Removing these from src/main/resources broke three local/CI flows that relied on them being present in the packaged artifact when the mysql/postgresql profile is active, with no other credentials supplied:

  • ./gradlew run / bootRun with -Dspring.profiles.active=postgresql or mysql (documented in README.md)
  • the embedded integrationTest auto-start (java -jar launch in uaa/build.gradle.kts)
  • CI's external-Tomcat integration test matrix (scripts/tomcat/integration_tests_tomcat.sh, .github/workflows/integration-tests.yml, mysql/postgresql matrix)

All three now supply the same root/changeme local-dev credentials via explicit -D system properties (still overridable) instead of relying on the packaged properties files. Verified by running bootRun -Dspring.profiles.active=postgresql against a real local Postgres — UAA started and Flyway created all tables as expected.

Test plan

  • ./gradlew :cloudfoundry-identity-uaa:bootRun -Dspring.profiles.active=postgresql -Ddatabase.url=jdbc:postgresql://localhost:5433/uaa against a local Postgres with a root/changeme superuser — UAA started, Flyway created all 16 tables
  • shellcheck scripts/tomcat/integration_tests_tomcat.sh — no new findings
  • CI mysql/postgresql integration test matrix (this PR)

@fhanik

fhanik commented Nov 13, 2025

Copy link
Copy Markdown
Contributor

rebased on develop branch

duanemay added 2 commits July 13, 2026 11:40
…tion tests

application-mysql.properties/application-postgresql.properties no longer ship
database.username/password/url, since those are packaged into the WAR. bootRun,
the embedded integrationTest auto-start, and the CI external-Tomcat integration
tests (scripts/tomcat/integration_tests_tomcat.sh) all relied on those defaults
to reach the root/changeme database that lib_db_helper.sh boots locally/in CI.
Supply the same values via -D system properties instead, so those flows keep
working without reintroducing the credentials into the shipped artifact.
duanemay added 3 commits July 13, 2026 12:47
Gradle's gradle.taskGraph.whenReady block only forwarded spring.profiles.active,
testId, and zones.paths.enabled into forked Test-task JVMs; arbitrary -D flags
passed on the command line (e.g. -Ddatabase.username) are never propagated to a
forked test JVM automatically. Once application-mysql.properties/application-
postgresql.properties stopped shipping database.username/password/url, any test
that builds a DatabaseConfiguration context (e.g. ClientAdminBootstrapProdEncoderTest)
under the mysql/postgresql profile got a null database URL and failed to create a
DataSource. Forward the same root/changeme local-dev credentials used for
bootRun/integrationTest/CI Tomcat into every Test task's active profile. Also
apply the same fix to bootWarRun for consistency.

Verified locally against a real Postgres: ClientAdminBootstrapProdEncoderTest now
passes under -Dspring.profiles.active=postgresql, reproducing and fixing the CI
db-integration-test/tomcat-integration-test failures on PR #3628.
The previous commit forwarded database.username/password/url into every Test
task, but the plain `test` task includes tests (DatabasePropertiesTest,
YamlServletProfileInitializerTest) that deliberately exercise their own
per-profile/custom database property fixtures (e.g. hsqldb's "sa" default, a
mysql URL pattern, a custom "donkey" YAML value). Since JVM system properties
take precedence over everything else in Spring's Environment, the blanket
override clobbered those fixtures and broke db-unit-test in CI. Restrict the
override to the integrationTest task, which is the one that actually needs it
(it connects to a real external mysql/postgresql with no per-test property
source of its own).

Verified locally: DatabasePropertiesTest and YamlServletProfileInitializerTest
pass again under -Dspring.profiles.active=postgresql, the full
:cloudfoundry-identity-server:test suite passes (4819/4820, the one failure is
an unrelated collation/locale artifact of the local Postgres install), and
ClientAdminBootstrapProdEncoderTest still passes under integrationTest.
…ncher

The mysql JDBC URL contains an unescaped & (...useSSL=true&trustServerCertificate=true).
The doFirst block builds a raw command string passed straight to `bash -c`, which
parses it fresh (unlike the CATALINA_OPTS case in integration_tests_tomcat.sh, where
the same value only ever appears via variable expansion, so control-operator lexing
doesn't apply). An unquoted & there is lexed as a background-job operator, splitting
the command mid-argument and silently truncating the java -jar invocation, which is
why db-integration-test (mysql-8.0/8.4/9) kept failing to start UAA within 300s while
the postgresql matrix (no & in its URL) passed. Single-quote each -D value.
@duanemay
duanemay marked this pull request as ready for review September 22, 2026 15:16
Copilot AI lite review requested due to automatic review settings September 22, 2026 15:16

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Unresolved critical and moderate findings affect database startup, shell handling, and packaged profile behavior.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 3 High severity · 1 Low severity

Open (4)
What changed in this PR

Moves local MySQL/PostgreSQL test database defaults out of packaged resources while supplying them explicitly for local and CI launchers.

Changes:

  • Adds database fixtures to test resources.
  • Adds Gradle and Tomcat runtime database arguments.
  • Leaves packaged profile files with driver configuration only.
File Change / final findings
uaa/​src/​test/​resources/​application-postgresql.properties Adds PostgreSQL test defaults.
uaa/​src/​test/​resources/​application-mysql.properties Adds MySQL test defaults.
uaa/​build.gradle.kts Configures boot and embedded integration startup. Critical (3 votes, line 294): apostrophes in overrides are not shell-escaped. Critical (1 vote, line 11): YAML-selected profiles may bypass injected properties.
server/​src/​test/​resources/​application-postgresql.properties Adds PostgreSQL test defaults.
server/​src/​test/​resources/​application-mysql.properties Adds MySQL test defaults.
server/​src/​main/​resources/​application-postgresql.properties Removes packaged defaults. Moderate (1 vote): platform-specific settings change to defaults. Nit (2 votes): documentation must describe the required database URL.
server/​src/​main/​resources/​application-mysql.properties Removes packaged defaults. Moderate (1 vote): database.caseinsensitive changes to its Java default. Nit (1 vote): documentation must describe the required database URL.
scripts/​tomcat/​integration_tests_tomcat.sh Supplies database options to Tomcat. Critical (1 vote, lines 45 and 182): raw & may be interpreted as a shell separator.
build.gradle.kts Configures integration-test and WAR-run database properties. Critical (1 vote, line 11): YAML-selected profiles may bypass injected properties.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

function local_database_catalina_opts() {
local profiles="$1"
if [[ ",${profiles}," == *,mysql,* ]]; then
echo "-Ddatabase.username=root -Ddatabase.password=changeme -Ddatabase.url=jdbc:mysql://127.0.0.1:3306/uaa?useSSL=true&trustServerCertificate=true"
Comment thread uaa/build.gradle.kts
Comment on lines +11 to +12
fun localDatabaseCredentialArgs(activeProfiles: String): Map<String, String> {
val profiles = activeProfiles.split(",").map { it.trim() }
Comment thread uaa/build.gradle.kts
// Single-quoted: this string is parsed fresh by `bash -c` below (not expanded from an
// already-set shell variable), so an unescaped `&` in the mysql JDBC URL would otherwise
// be lexed as a background-job operator and silently truncate the java invocation.
val databaseArgsList = localDatabaseCredentialArgs(springProfile).map { (key, value) -> "-D$key='$value'" }
database.caseinsensitive=false
database.default-url=jdbc:postgresql:uaa No newline at end of file
# This file is required by : org.cloudfoundry.identity.uaa.db.beans.DatabaseConfiguration
database.driverClassName=org.postgresql.Driver No newline at end of file

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

3 participants