carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1// Package dbdoortest builds real litestream replicas for the db door's tests,
2// on both sides of the wire (internal/console serves one, internal/dbdoor and
3// the CLI restore one). A fake replica would prove only that the fake agrees
4// with itself; these are written by litestream's own replication code, in
5// the layout its file client reads, so a restore through the door is the
6// restore production runs.
7//
8// Test support only: nothing outside a _test.go file may import it.
9package dbdoortest
10
11import (
12 "context"
13 "database/sql"
14 "fmt"
15 "path/filepath"
16 "testing"
17 "time"
18
19 "github.com/benbjohnson/litestream"
20 lsfile "github.com/benbjohnson/litestream/file"
21 _ "modernc.org/sqlite"
22)
23
24// Rows is how many rows each batch inserts into table t.
25const Rows = 10
26
27// Replicate creates a WAL-mode SQLite database with a table t(id, body) and
28// replicates it into dir in `batches` separate syncs, so the replica holds
29// several L0 files rather than one. It returns the source database's path;
30// the source holds batches*Rows rows when it returns.
31func Replicate(t testing.TB, dir string, batches int) string {
32 t.Helper()
33 src := filepath.Join(t.TempDir(), "source.db")
34 db, err := sql.Open("sqlite", src)
35 if err != nil {
36 t.Fatal(err)
37 }
38 defer db.Close()
39 if _, err := db.Exec(`PRAGMA journal_mode=WAL; CREATE TABLE t (id INTEGER PRIMARY KEY, body TEXT)`); err != nil {
40 t.Fatal(err)
41 }
42 for b := 0; b < batches; b++ {
43 for i := 0; i < Rows; i++ {
44 if _, err := db.Exec(`INSERT INTO t (body) VALUES (?)`, fmt.Sprintf("row-%d-%d", b, i)); err != nil {
45 t.Fatal(err)
46 }
47 }
48 Sync(t, src, dir)
49 }
50 return src
51}
52
53// Sync replicates the source's committed state into dir once, the way the
54// lease package's Checkpoint does: open, one explicit sync, close.
55func Sync(t testing.TB, src, dir string) {
56 t.Helper()
57 ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
58 defer cancel()
59 ldb := litestream.NewDB(src)
60 ldb.SetMetaPath(filepath.Join(filepath.Dir(src), ".dbdoortest-litestream"))
61 ldb.MonitorInterval = 0
62 ldb.Replica = litestream.NewReplicaWithClient(ldb, lsfile.NewReplicaClient(dir))
63 ldb.Replica.MonitorEnabled = false
64 store := litestream.NewStore([]*litestream.DB{ldb}, litestream.CompactionLevels{{Level: 0}})
65 store.CompactionMonitorEnabled = false
66 store.L0RetentionCheckInterval = 0
67 store.SetRetentionEnabled(false)
68 if err := store.Open(ctx); err != nil {
69 t.Fatal(err)
70 }
71 syncErr := ldb.SyncAndWait(ctx)
72 if err := store.Close(ctx); err != nil {
73 t.Fatal(err)
74 }
75 if syncErr != nil {
76 t.Fatal(syncErr)
77 }
78}
79