Run Gradle on Java 17 or newer; production code uses --release 11. Use -PtestJavaHome="C:/Program Files/Zulu/zulu-11" to run tests on Java 11. Other operating systems can supply their equivalent installed Java home.
- ./gradlew test: configuration, budgets, bounded admission, cancellation, rollback, state reset, real SQLite/H2/DuckDB files, and deterministic dependency download, offline cache, corruption, HTTP failure and catalog validation checks.
- ./gradlew :plugin:backendIntegrationTest: six disposable Docker servers, CRUD, batches, transaction capabilities, owner isolation and cleanup.
- ./gradlew :plugin:backendBenchmark: all nine engines against direct drivers. Warm-up and rotated repeated rounds; no speed-dependent assertions. Requires Docker.
- ./gradlew :plugin:packagedBackendTest: copies only the release plugin JAR into build/test-installation and invokes the production bootstrap in an isolated URLClassLoader. The first run downloads locked Maven dependencies; later runs use validated cache entries. JUnit then tests real backends, shared API/driver class identity, Hikari relocation and separate JDBC service descriptors. No development API/driver jars are supplied to that loader. This is a JavaExec task, not a Gradle Test task; JUnit failures still produce a nonzero process exit and fail the build.
- ./gradlew :plugin:mariaDbTest: optional local MariaDB at 127.0.0.1:3306. Set DATAVAULT_TEST_USER and DATAVAULT_TEST_PASSWORD. Only dedicated datavault_test_ tables are modified; the datavault_test database is retained.
- ./gradlew :plugin:jdbcBenchmark: original SQLite/local MariaDB comparison, requiring the same local credentials.
Pull images before Docker tasks to separate downloads from startup:
docker pull mysql:8.4
docker pull mariadb:11.4
docker pull postgres:17
docker pull mongo:7
docker pull redis:7.4
docker pull clickhouse/clickhouse-server:25.8Fixtures use unique datavault-test- names, the datavault.test=true label, ephemeral loopback ports and no persistent volumes. Startup retries have a deadline; test assertions are never retried. Containers are removed in finally/close paths. If a JVM is forcibly killed, inspect containers with that exact label and remove only leftover test containers, never unrelated Docker resources.
Reports and raw measurements belong in reports/performance, not this guide. JDBC paths share an identically tuned pool, identical callbacks and one worker. Native paths use equivalently configured independently owned clients. Baselines do not use DataVault admission or transaction code.
Compare DataVault primarily with a plugin-style asynchronous baseline. Synchronous JDBC has different scheduling costs. Fast embedded reads expose overhead; slower queries can hide it in noise. These are local closed-loop observations, not guarantees.
Arbitrary callbacks can block forever. Shutdown drains accepted work without a forced deadline. Completion handlers must be short; use explicitly supplied executors for expensive transformations. Queue limits count operations, not bytes. Canonical paths cannot detect hard links or external file replacement. Pools cannot isolate shared server locks, CPU, disk, JVM or network.
MongoDB pools are per server and add monitoring sockets. Redis and embedded engines also own native threads. Application-worker reservations are not an OS thread or total physical-connection cap. Live-server smoke tests are separate from the isolated backend and thin-JAR tests.
The isolated loader's parent contains only the Java platform, not the server's Guava/Netty/native API versions. A live Bukkit smoke test with realistic server and dependent-plugin classpaths is necessary to validate those additional conflicts.
Run ./gradlew build :plugin:serverSmokeJar to create the release plugin and a
separate plugin/build/server-smoke-fixture/DataVault-Smoke-<version>.jar.
Install both only in an isolated test server, never a production server. The fixture
does not bundle API or driver classes and declares a hard dependency on DataVault.
It performs SQLite/H2/DuckDB transactions and CRUD, verifies native API class identity,
and unregisters each owner. Success appears as SMOKE PASS log markers; failures
appear as SMOKE FAIL with an exception.
Optional MongoDB and Redis checks read mongo-uri and redis-uri from
plugins/DataVaultSmoke/config.yml. Use only disposable dedicated endpoints: the
fixture modifies its datavault_test_live collection and Redis key. These native
checks are skipped if endpoints are absent. The fixture uses asynchronous callbacks
and does not block the platform thread or access worlds/entities from workers.
Use loopback bindings and a fresh world. Preserve the original service directory and its EULA acceptance rather than modifying existing worlds or installing the fixture in-place. Stop test servers gracefully before removing disposable containers. The supplied Purpur 26.3 and Lophine 26.3 cores were verified on Java 25; observations are recorded in the performance report's live-server follow-up. These runs do not replace oldest-supported Bukkit testing or loaded-region stress tests.