Skip to content

Commit fa7bad4

Browse files
committed
mount: Add tests for CommitJournal incremental checksumming
1 parent 129daad commit fa7bad4

File tree

1 file changed

+111
-0
lines changed

1 file changed

+111
-0
lines changed

cmd/litefs/mount_test.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,117 @@ func TestSingleNode_RecoverFromInitialRollback(t *testing.T) {
298298
}
299299
}
300300

301+
// Ensure that CommitJournal correctly computes the incremental checksum when
302+
// pages are modified multiple times.
303+
func TestSingleNode_JournalMultipleUpdates(t *testing.T) {
304+
// This test only applies to the rollback journal, but it passes in WAL mode.
305+
306+
cmd := runMountCommand(t, newMountCommand(t, t.TempDir(), nil))
307+
db := testingutil.OpenSQLDB(t, filepath.Join(cmd.Config.FUSE.Dir, "db"))
308+
309+
// Disable page cache so dirty pages are written immediately.
310+
if _, err := db.Exec(`PRAGMA cache_size = 0`); err != nil {
311+
t.Fatal(err)
312+
}
313+
314+
if _, err := db.Exec(`CREATE TABLE t (x)`); err != nil {
315+
t.Fatal(err)
316+
}
317+
for i := 0; i < 500; i++ {
318+
if _, err := db.Exec(`INSERT INTO t VALUES (?)`, strings.Repeat("x", 60)); err != nil {
319+
t.Fatal(err)
320+
}
321+
}
322+
323+
tx, err := db.Begin()
324+
if err != nil {
325+
t.Fatal(err)
326+
}
327+
defer func() { _ = tx.Rollback() }()
328+
329+
// Update all pages (LiteFS will store the previous page checksum).
330+
if _, err := tx.Exec(`UPDATE t SET x = ?`, strings.Repeat("y", 60)); err != nil {
331+
t.Fatal(err)
332+
}
333+
// Update all pages again (LiteFS should not update the previous page checksum).
334+
if _, err := tx.Exec(`UPDATE t SET x = ?`, strings.Repeat("z", 60)); err != nil {
335+
t.Fatal(err)
336+
}
337+
if err := tx.Commit(); err != nil {
338+
t.Fatal(err)
339+
}
340+
}
341+
342+
// Ensure that CommitJournal correctly computes the checksum when the commit
343+
// truncates dirty pages.
344+
func TestSingleNode_JournalTruncateDirtyPages(t *testing.T) {
345+
if testingutil.IsWALMode() {
346+
// The page count assertion will fail in WAL mode.
347+
t.Skip("test only applies to rollback journal, skipping")
348+
}
349+
350+
cmd := runMountCommand(t, newMountCommand(t, t.TempDir(), nil))
351+
db := testingutil.OpenSQLDB(t, filepath.Join(cmd.Config.FUSE.Dir, "db"))
352+
353+
// Make sure the database is truncated on commit.
354+
if _, err := db.Exec(`PRAGMA auto_vacuum = FULL`); err != nil {
355+
t.Fatal(err)
356+
}
357+
358+
if _, err := db.Exec(`CREATE TABLE t (id INTEGER PRIMARY KEY, x)`); err != nil {
359+
t.Fatal(err)
360+
}
361+
for i := 0; i < 500; i++ {
362+
if _, err := db.Exec(`INSERT INTO t (x) VALUES (?)`, strings.Repeat("x", 60)); err != nil {
363+
t.Fatal(err)
364+
}
365+
}
366+
367+
var pageCount int
368+
if err := db.QueryRow(`PRAGMA page_count`).Scan(&pageCount); err != nil {
369+
t.Fatal(err)
370+
}
371+
t.Logf("pre-commit pageCount = %d", pageCount)
372+
if got, want := pageCount, 8; got <= want {
373+
t.Fatalf("got %d pages, want more than %d", got, want)
374+
}
375+
376+
tx, err := db.Begin()
377+
if err != nil {
378+
t.Fatal(err)
379+
}
380+
defer func() { _ = tx.Rollback() }()
381+
382+
// Make all pages dirty.
383+
if _, err := tx.Exec(`UPDATE t SET x = ?`, strings.Repeat("y", 60)); err != nil {
384+
t.Fatal(err)
385+
}
386+
// Truncate the database.
387+
if _, err := tx.Exec(`DELETE FROM t WHERE id > ?`, 100); err != nil {
388+
t.Fatal(err)
389+
}
390+
if err := tx.Commit(); err != nil {
391+
t.Fatal(err)
392+
}
393+
394+
var count int
395+
if err := db.QueryRow(`SELECT COUNT(*) FROM t`).Scan(&count); err != nil {
396+
t.Fatal(err)
397+
}
398+
if got, want := count, 100; got != want {
399+
t.Fatalf("count=%d, want %d", got, want)
400+
}
401+
402+
// Make sure the database was truncated.
403+
if err := db.QueryRow(`PRAGMA page_count`).Scan(&pageCount); err != nil {
404+
t.Fatal(err)
405+
}
406+
t.Logf("post-commit pageCount = %d", pageCount)
407+
if got, want := pageCount, 8; got >= want {
408+
t.Fatalf("got %d pages, want less than %d", got, want)
409+
}
410+
}
411+
301412
func TestSingleNode_DropDB(t *testing.T) {
302413
cmd0 := runMountCommand(t, newMountCommand(t, t.TempDir(), nil))
303414
dsn := filepath.Join(cmd0.Config.FUSE.Dir, "db")

0 commit comments

Comments
 (0)