Files
ruoyi-vue-pro/docs/education/migration/issues/EDU-016-postgresql-persistence-tests.md

3.9 KiB

EDU-016 — Move PostgreSQL-specific Education persistence tests off H2

  • Status: done — focused PostgreSQL persistence suite passes against the reachable postgresdb seam
  • Type: test infrastructure / PostgreSQL integration
  • Phase: 0 / database prerequisite
  • Blockers: EDU-002, EDU-005 for final schema ownership

Confirmed defect

Education unit tests use H2 with MODE=MYSQL, while production Mapper SQL intentionally uses PostgreSQL ON CONFLICT. H2 rejects the annotated SQL for favorites, wrong-question idempotency, unified answer/submit idempotency, and review-session conflict handling. Switching H2 to PostgreSQL mode does not solve this: H2 still rejects ON CONFLICT and also exposes Boolean/integer compatibility differences.

This prevents the full Practice/Wrong/Favorite regression suite from exercising production persistence semantics.

Outcome

PostgreSQL-specific persistence behavior runs against real ephemeral PostgreSQL in the test suite, while fast database-independent tests may remain on H2 where their SQL is portable.

Scope

  • Select the repository-standard PostgreSQL integration-test mechanism, preferably Testcontainers or an existing project fixture.
  • Move tests that execute ON CONFLICT, PostgreSQL JSON/JSONB, identity, Boolean, or concurrency semantics onto PostgreSQL.
  • Keep controller and pure domain tests database-independent.
  • Align test schema with module-owned Flyway after EDU-005/EDU-006; avoid maintaining a divergent hand-written full schema long term.
  • Cover at least:
    • IdempotencyStoreMapper.insertIgnore;
    • wrong-question idempotency insert;
    • favorite upsert;
    • review-session insert-ignore;
    • concurrent answer and submit claims.

Acceptance criteria

  • No test relies on H2 to validate PostgreSQL ON CONFLICT semantics.
  • PostgreSQL tests execute the same Mapper SQL as production.
  • Test database is isolated and disposable.
  • Schema setup uses Flyway or an explicitly temporary bridge with an exit ticket.
  • Concurrency tests are stable and prove unique-constraint behavior.
  • CI prerequisites and local commands are documented.

Verification

Completed against the existing reachable postgresdb service with credentials supplied only through EDU_TEST_POSTGRES_* environment variables:

mvn -pl yudao-module-education \
  -Dtest=PracticeSessionMapperTest,FavoriteServiceImplTest,PracticeAnswerServiceImplTest,PracticeSubmitServiceImplTest,PracticeSubmitProjectionIntegrationTest,WrongQuestionServiceImplTest test

Result: 140 tests passed, 0 failures, 0 errors. The same 140-test suite also passed with JUnit class parallelism explicitly enabled, proving the shared schema resource lock prevents class-level collisions. The suite executes production Mapper SQL on PostgreSQL, including ON CONFLICT and JSONB behavior. A JUnit resource lock serializes PostgreSQL test classes that share one random JVM-scoped schema; each class closes its Spring context before the inherited lifecycle drops and recreates that schema, preventing cached contexts from reusing a dropped schema.

The temporary schema bridge was removed by EDU-006. PostgreSQL persistence tests now create their disposable random schema through the module-owned Flyway chain (V4010, V4020, V4030) and retain only clean.sql for per-test data isolation.

Local/CI prerequisites:

  • a reachable disposable PostgreSQL database;
  • PostgreSQL JDBC connectivity from the Maven process;
  • non-blank EDU_TEST_POSTGRES_HOST, EDU_TEST_POSTGRES_PORT, EDU_TEST_POSTGRES_DB, EDU_TEST_POSTGRES_USER, and EDU_TEST_POSTGRES_PASSWORD values.

No Testcontainers or other external dependency was added. No PostgreSQL Flyway migration was executed or authorized by this ticket.

Risk and rollback

  • Risk: Medium CI/runtime cost; high value for persistence confidence.
  • Rollback: Keep prior fast tests temporarily, but do not restore false H2 coverage claims for PostgreSQL SQL.