mirror of
https://github.com/syncthing/syncthing.git
synced 2026-04-04 22:53:42 -04:00
@@ -9,6 +9,7 @@ package sqlite
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/syncthing/syncthing/internal/db"
|
||||
"github.com/syncthing/syncthing/internal/itererr"
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
)
|
||||
@@ -138,6 +139,211 @@ func TestBlocksDeleted(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDropBlockIndex(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
sdb, err := Open(t.TempDir())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(func() { sdb.Close() })
|
||||
|
||||
// Insert files with blocks
|
||||
files := []protocol.FileInfo{
|
||||
genFile("a", 3, 0),
|
||||
genFile("b", 2, 0),
|
||||
}
|
||||
if err := sdb.Update(folderID, protocol.LocalDeviceID, files); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Verify blocks exist
|
||||
hits, err := itererr.Collect(sdb.AllLocalBlocksWithHash(folderID, files[0].Blocks[0].Hash))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(hits) == 0 {
|
||||
t.Fatal("expected block hits before drop")
|
||||
}
|
||||
|
||||
// Drop the block index
|
||||
if err := sdb.DropBlockIndex(folderID); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Verify blocks are gone
|
||||
hits, err = itererr.Collect(sdb.AllLocalBlocksWithHash(folderID, files[0].Blocks[0].Hash))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(hits) != 0 {
|
||||
t.Fatal("expected no block hits after drop")
|
||||
}
|
||||
|
||||
// Dropping again should be a no-op (already empty)
|
||||
if err := sdb.DropBlockIndex(folderID); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Dropping a nonexistent folder should be fine
|
||||
if err := sdb.DropBlockIndex("nonexistent"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPopulateBlockIndex(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
sdb, err := Open(t.TempDir())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(func() { sdb.Close() })
|
||||
|
||||
// Insert files with blocks
|
||||
files := []protocol.FileInfo{
|
||||
genFile("a", 3, 0),
|
||||
genFile("b", 2, 0),
|
||||
}
|
||||
if err := sdb.Update(folderID, protocol.LocalDeviceID, files); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Collect the original block entries for comparison
|
||||
origHitsA, err := itererr.Collect(sdb.AllLocalBlocksWithHash(folderID, files[0].Blocks[0].Hash))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(origHitsA) != 1 {
|
||||
t.Fatal("expected one hit for block a[0]")
|
||||
}
|
||||
|
||||
// Drop the block index
|
||||
if err := sdb.DropBlockIndex(folderID); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Populate it back from existing blocklists
|
||||
if err := sdb.PopulateBlockIndex(folderID); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Verify all blocks are back
|
||||
for i, f := range files {
|
||||
for j, b := range f.Blocks {
|
||||
hits, err := itererr.Collect(sdb.AllLocalBlocksWithHash(folderID, b.Hash))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(hits) == 0 {
|
||||
t.Errorf("file %d block %d: expected hits after populate", i, j)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Populating again should be a no-op (not empty)
|
||||
if err := sdb.PopulateBlockIndex(folderID); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPopulateBlockIndexSkipsRemoteFiles(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
sdb, err := Open(t.TempDir())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(func() { sdb.Close() })
|
||||
|
||||
// Insert a local file (blocks indexed) and a remote file (blocks not indexed)
|
||||
localFile := genFile("local", 2, 0)
|
||||
if err := sdb.Update(folderID, protocol.LocalDeviceID, []protocol.FileInfo{localFile}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
remoteFile := genFile("remote", 2, 1)
|
||||
if err := sdb.Update(folderID, protocol.DeviceID{42}, []protocol.FileInfo{remoteFile}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Drop and repopulate
|
||||
if err := sdb.DropBlockIndex(folderID); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := sdb.PopulateBlockIndex(folderID); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Local file blocks should be present
|
||||
hits, err := itererr.Collect(sdb.AllLocalBlocksWithHash(folderID, localFile.Blocks[0].Hash))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(hits) == 0 {
|
||||
t.Error("expected hits for local file blocks")
|
||||
}
|
||||
|
||||
// Remote file blocks should not be present (blocks are only
|
||||
// indexed for local files)
|
||||
hits, err = itererr.Collect(sdb.AllLocalBlocksWithHash(folderID, remoteFile.Blocks[0].Hash))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(hits) != 0 {
|
||||
t.Error("expected no hits for remote file blocks")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSkipBlockIndexOnUpdate(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
sdb, err := Open(t.TempDir())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(func() { sdb.Close() })
|
||||
|
||||
// Insert a file with SkipBlockIndex
|
||||
file := genFile("a", 3, 0)
|
||||
if err := sdb.Update(folderID, protocol.LocalDeviceID, []protocol.FileInfo{file}, db.WithSkipBlockIndex()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Blocks should not be indexed
|
||||
hits, err := itererr.Collect(sdb.AllLocalBlocksWithHash(folderID, file.Blocks[0].Hash))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(hits) != 0 {
|
||||
t.Fatal("expected no block hits with SkipBlockIndex")
|
||||
}
|
||||
|
||||
// The blocklist should still be stored (file info is retrievable with blocks)
|
||||
fi, ok, err := sdb.GetDeviceFile(folderID, protocol.LocalDeviceID, "a")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !ok {
|
||||
t.Fatal("file not found")
|
||||
}
|
||||
if len(fi.Blocks) != 3 {
|
||||
t.Fatalf("expected 3 blocks in file info, got %d", len(fi.Blocks))
|
||||
}
|
||||
|
||||
// Populate should fill in the blocks
|
||||
if err := sdb.PopulateBlockIndex(folderID); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
hits, err = itererr.Collect(sdb.AllLocalBlocksWithHash(folderID, file.Blocks[0].Hash))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(hits) != 1 {
|
||||
t.Fatal("expected one hit after populate")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoteSequence(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user