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

65 lines
3.9 KiB
Markdown

# 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
- [x] No test relies on H2 to validate PostgreSQL `ON CONFLICT` semantics.
- [x] PostgreSQL tests execute the same Mapper SQL as production.
- [x] Test database is isolated and disposable.
- [x] Schema setup uses Flyway or an explicitly temporary bridge with an exit ticket.
- [x] Concurrency tests are stable and prove unique-constraint behavior.
- [x] 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:
```bash
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.