lib/db: Dont recurse on flush (fixes #6905) (#6906)

Or else we crash.

Co-authored-by: Jakob Borg <jakob@kastelo.net>
Co-authored-by: Simon Frei <freisim93@gmail.com>
This commit is contained in:
Audrius Butkevicius
2020-08-19 13:13:44 +02:00
committed by GitHub
co-authored by Jakob Borg Simon Frei
parent 96e35aa7f5
commit cbbc262161
2 changed files with 57 additions and 1 deletions
+48
View File
@@ -9,6 +9,8 @@ package db
import (
"bytes"
"context"
"fmt"
"os"
"testing"
"github.com/syncthing/syncthing/lib/db/backend"
@@ -795,6 +797,52 @@ func TestUpdateTo14(t *testing.T) {
}
}
func TestFlushRecursion(t *testing.T) {
// Verify that a commit hook can write to the transaction without
// causing another flush and thus recursion.
// Badger doesn't work like this.
if os.Getenv("USE_BADGER") != "" {
t.Skip("Not supported on Badger")
}
db := NewLowlevel(backend.OpenMemory())
defer db.Close()
// A commit hook that writes a small piece of data to the transaction.
hookFired := 0
hook := func(tx backend.WriteTransaction) error {
err := tx.Put([]byte(fmt.Sprintf("hook-key-%d", hookFired)), []byte(fmt.Sprintf("hook-value-%d", hookFired)))
if err != nil {
t.Fatal(err)
}
hookFired++
return nil
}
// A transaction.
tx, err := db.NewWriteTransaction(hook)
if err != nil {
t.Fatal(err)
}
defer tx.Release()
// Write stuff until the transaction flushes, thus firing the hook.
i := 0
for hookFired == 0 {
err := tx.Put([]byte(fmt.Sprintf("key-%d", i)), []byte(fmt.Sprintf("value-%d", i)))
if err != nil {
t.Fatal(err)
}
i++
}
// The hook should have fired precisely once.
if hookFired != 1 {
t.Error("expect one hook fire, not", hookFired)
}
}
func numBlockLists(db *Lowlevel) (int, error) {
it, err := db.Backend.NewPrefixIterator([]byte{KeyTypeBlockList})
if err != nil {