Cassandra¶
Real Cassandra in a container or wired to an existing cluster. CQL execute/query, prepared statements via raw session(), keyspace migrations, pause/unpause.
Cassandra — wizard-synced snippet
Gradle
Stove configuration
Stove().with {
cassandra {
CassandraSystemOptions(
configureExposedConfiguration = { cfg ->
listOf("cassandra.contact-points=${cfg.contactPoints}")
}
)
}
}
Test DSL
In 30 seconds
Register cassandra { CassandraSystemOptions(keyspace, datacenter, ...) }. shouldExecute(cql) and shouldQuery(cql) { resultSet -> }. Use session() for prepared / bound statements. Create keyspace and tables in a CassandraMigration.
Configure¶
Stove().with {
cassandra {
CassandraSystemOptions(
keyspace = "testks",
datacenter = "datacenter1",
configureExposedConfiguration = { cfg ->
listOf(
"cassandra.contact-points=${cfg.contactPoints}",
"cassandra.keyspace=${cfg.keyspace}",
"cassandra.datacenter=${cfg.datacenter}"
)
}
)
}
}.run()
Migrations¶
class CreateKeyspaceAndTable : CassandraMigration {
override val order = 1
override suspend fun execute(session: CqlSession) {
session.execute(
"""
CREATE KEYSPACE IF NOT EXISTS testks
WITH replication = {'class':'SimpleStrategy', 'replication_factor':1}
""".trimIndent()
)
session.execute(
"""
CREATE TABLE IF NOT EXISTS testks.events (
id UUID PRIMARY KEY,
type TEXT,
ts TIMESTAMP
)
""".trimIndent()
)
}
}
cassandra {
CassandraSystemOptions(/* ... */).migrations {
register<CreateKeyspaceAndTable>()
}
}
DSL¶
Execute + query¶
stove {
cassandra {
shouldExecute("INSERT INTO testks.events (id, type, ts) VALUES (uuid(), 'created', toTimestamp(now()))")
shouldQuery("SELECT * FROM testks.events WHERE type = 'created' ALLOW FILTERING") { rs ->
val rows = rs.all()
rows shouldHaveSize 1
}
}
}
Prepared / bound statements¶
stove {
cassandra {
val stmt = session().prepare("INSERT INTO testks.events (id, type, ts) VALUES (?, ?, ?)")
session().execute(stmt.bind(UUID.randomUUID(), "shipped", Instant.now()))
}
}
Cleanup hook¶
cassandra {
CassandraSystemOptions(
keyspace = "testks",
cleanup = { session -> session.execute("TRUNCATE testks.events") },
/* ... */
)
}
Pause / unpause (container mode)¶
Pitfalls¶
| Symptom | Fix |
|---|---|
Cannot achieve consistency level |
Replication factor 1 in dev; raise only when you're testing multi-DC |
Query needs ALLOW FILTERING |
Add a secondary index or use the partition key; not for production but fine in tests |
KeyspaceNotFound |
Create in a migration before tests run |
Pairs well with¶
- Provided Instances for shared CI clusters
- Recipes for multi-system flows