Skip to content
Exposed docs1.11

Testing and Operations

Latest stable Based on Exposed release 1.11.0

Test the boundary that can fail in production: driver behavior, transaction ownership, replay, cancellation, and external service configuration. An application-context test or an H2 test alone does not prove those properties.

LevelWhat it provesWhat it does not prove
Unit testMapping, branching, retry classification, pure SQL generationDriver, server, transaction, or lifecycle behavior
H2 integration testFast repository contract and basic JDBC/R2DBC wiringProduction dialect, locking, extension, or network behavior
TestcontainersReal engine and driver path used by the testProduction topology, credentials, TLS, capacity, or managed-service policy
Environment-gated smoke testSelected external service can be reached with current configurationRepeatable performance or broad failure recovery
Load/benchmark runOne declared workload under one declared environmentA universal library or database ranking
Terminal window
./gradlew :bluetape4k-exposed-ktor:test
./gradlew :bluetape4k-exposed-spring-boot-jdbc:test
./gradlew :bluetape4k-exposed-spring-boot-r2dbc:test
./gradlew :bluetape4k-exposed-spring-boot-batch:test
./gradlew :bluetape4k-exposed-spring-modulith:test
./gradlew :bluetape4k-exposed-batch:test

For runnable examples, use their exact paths:

Terminal window
./gradlew :examples-ktor-exposed-demo:test
./gradlew :exposed-spring-boot-jdbc-demo:test
./gradlew :exposed-spring-boot-r2dbc-demo:test
./gradlew :examples-exposed-bigquery-dry-run:test
./gradlew :examples-exposed-clickhouse-oltp-olap:test

The ClickHouse example requires Docker. The BigQuery dry-run example uses a mock REST service, so it requires no cloud credentials and does not prove real project permission, location, quota, or execution results.

For JDBC and Spring JDBC, verify that two writes in one business operation roll back together. For R2DBC, verify the explicit suspendTransaction boundary and cancellation propagation. For the lightweight batch runner, fail after a writer call and confirm the documented replay behavior: the checkpoint advances only after a successful write, so writers should be idempotent. Use a persistent checkpoint repository when restart must survive a process loss.

Spring Batch has a different runtime. Its reader persists lastKey in ExecutionContext, the writer joins the chunk transaction, and the chunk commit advances restart state. Use a stable, monotonically ordered key and test a crash between chunks.

Batch runtime and restart boundaries

  • Report readiness only after the required database registry or pool can serve work.
  • Keep liveness independent from a transient database outage unless restart is the intended recovery.
  • On shutdown, stop admitting work, cancel or drain in-flight operations, persist batch state, and close pools.
  • Record transaction failures, retries, skipped batch items, checkpoint position, pool saturation, and query latency.
  • Do not log credentials, unredacted SQL parameters, or serialized secrets.

Spring Modulith’s publication table tracks event delivery. It is operational state, not an audit history. Monitor incomplete publications and choose update, delete, or archive completion semantics deliberately.

The benchmark module uses short JMH runs by default. Its H2 PostgreSQL-mode JDBC/R2DBC measurements are useful for detecting local regressions, not for predicting production database performance. Redis benchmarks require a separately running Redis service. Record CPU, JVM, operating system, forks, warmup, iterations, database/service version, and data size whenever publishing a result.

Continue with the benchmark module for exact tasks and limitations.