Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 37 additions & 19 deletions transact/src/test/java/dev/dbos/transact/utils/PgContainer.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
Expand Down Expand Up @@ -45,7 +46,7 @@ static JdbcDatabaseContainer<?> acquire() {
var jdbcUrl = container.getJdbcUrl().replaceFirst("/[^/]+$", "/" + DB_NAME);
try (var conn =
DriverManager.getConnection(jdbcUrl, container.getUsername(), container.getPassword())) {
truncateDbosTables(conn);
resetDbosTables(conn);
} catch (SQLException e) {
throw new RuntimeException(e);
}
Expand All @@ -63,25 +64,42 @@ static void release(JdbcDatabaseContainer<?> c) {
POOL.offer(c);
}

public static void truncateDbosTables(Connection conn) throws SQLException {
// truncate the DBOS tables from the test DB before returning to the pool
var truncate =
"""
TRUNCATE TABLE
"dbos".workflow_status,
"dbos".operation_outputs,
"dbos".workflow_events,
"dbos".workflow_events_history,
"dbos".notifications,
"dbos".event_dispatch_kv,
"dbos".streams,
"dbos".application_versions,
"dbos".workflow_schedules,
"dbos".queues
CASCADE
""";
/**
* Empties every DBOS table, leaving the schema in place.
*
* <p>{@code DELETE}, not {@code TRUNCATE}: CockroachDB implements {@code TRUNCATE} as a schema
* change, so it prices like {@code CREATE INDEX} however few rows a table holds. Measured against
* this schema it costs 1.16s where the equivalent deletes cost 0.05s — and a pooled container is
* reset once per test, roughly 900 times a run. {@code TRUNCATE} would win only once a table is
* big enough for row count to dominate, which no test fixture is.
*
* <p>The table list comes from the catalogue rather than a hard-coded list, so a migration that
* adds a table cannot silently leave it uncleaned. Deleting from all of them in one statement
* batch is safe in any order — emptying everything cannot strand a foreign key.
*/
public static void resetDbosTables(Connection conn) throws SQLException {
var tables = new ArrayList<String>();
try (var stmt = conn.createStatement();
var rs =
stmt.executeQuery(
"""
SELECT table_name FROM information_schema.tables
WHERE table_schema = 'dbos' AND table_name <> 'dbos_migrations'
ORDER BY table_name
""")) {
while (rs.next()) {
tables.add(rs.getString(1));
}
}
if (tables.isEmpty()) {
return;
}
var deletes = new StringBuilder();
for (var table : tables) {
deletes.append("DELETE FROM \"dbos\".\"").append(table).append("\";");
}
try (var stmt = conn.createStatement()) {
stmt.execute(truncate);
stmt.execute(deletes.toString());
}
}

Expand Down
Loading