Gemini is an automatic randomized testing suite for the Scylla database. It operates by generating random mutations (INSERT, UPDATE, DELETE) and verifying them (SELECT) using the CQL protocol across two clusters: a system under test (SUT) and a test oracle.
pkg/contains everything that is needed forgeminiprojectdocs/contain project documentation and always keep it up to date, especially the architecture diagrams and if something is new, add it to the documentationscripts/contain useful scripts for development and testingdocker/contains dockerfiles for building the project, and it containsdocker-composefiles for easy development environment setup, also used in CI
- Language: Go 1.25
- Architecture: CLI application with modular package structure
- Database: Scylla/Cassandra using CQL protocol
- Testing: Randomized testing with statistical distributions
- Always use
for rangeinstead offorwithi++when iterating, this is the new syntax from Go 1.25 Example:for i := 0; i < 10; i++should be replaced withfor i := range 10. If theiis not needed it can be omitted. This is also true when using some integer variable as a counter.for i := 0; i < VARIABLE; i++can be replaced withfor i := range VARIABLE, alsoican be omitted. - Always assume
go1.25. Prefergocommands that work with Go 1.25. - Keep
go.modgo 1.25. Do not add atoolchainline when updating thegoline (Go 1.25 no longer auto-adds it). - Use the new
go.modignoredirective to exclude non-packages (e.g., examples, scratch) from./... - Prefer standard library first; avoid third-party deps unless asked.
- Slice stack-allocation opportunities (new in 1.25) and avoid unsafe pointer aliasing.
- Use testing/synctest for flaky/racy tests.
- Consider the container-aware GOMAXPROCS defaults when benchmarking.
- DWARF 5 debug info by default
- Add a
synctestbased test that removestime.Sleepand waits deterministically. - Use
go test -raceto detect data races. - Always use in tests for context
t.Context()and for benchmarkingb.Context(), there are new go 1.24 function, and they better and avoid linting errors. - Use
t.Cleanup()to register cleanup functions in tests instead ofdeferto ensure proper execution order. - Use
t.Parallel()to run tests in parallel.
Always run go vet ./... and address:
- waitgroup analyzer: fix misplaced (*sync.WaitGroup).Add calls.
- hostport analyzer: replace fmt.Sprintf("%s:%d", host, port) with net.JoinHostPort(host, strconv.Itoa(port)).
- IMPORTANT THING: Always use
-tags testingand-racewhen running tests locally and in CI.go test -tags testing -race ./pkg/...
- When writing new tests, always use
t.Context()for context in tests - IMPORTANT THING: Running tests locally and in CI should be deterministic, so use environment variables to set up
ScyllaDB clusters
GEMINI_ORACLE_CLUSTER_IP=192.168.100.2 GEMINI_TEST_CLUSTER_IP=192.168.100.3 GEMINI_USE_DOCKER_SCYLLA=true