|
@@ -18,6 +18,7 @@ import (
|
|
|
"path/filepath"
|
|
|
"runtime"
|
|
|
"runtime/pprof"
|
|
|
+ "sort"
|
|
|
"strconv"
|
|
|
"strings"
|
|
|
"sync"
|
|
@@ -3537,3 +3538,154 @@ func TestFolderAPIErrors(t *testing.T) {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+func TestRenameSequenceOrder(t *testing.T) {
|
|
|
+ wcfg, fcfg := tmpDefaultWrapper()
|
|
|
+ m := setupModel(wcfg)
|
|
|
+ defer cleanupModel(m)
|
|
|
+
|
|
|
+ numFiles := 20
|
|
|
+
|
|
|
+ ffs := fcfg.Filesystem()
|
|
|
+ for i := 0; i < numFiles; i++ {
|
|
|
+ v := fmt.Sprintf("%d", i)
|
|
|
+ must(t, writeFile(ffs, v, []byte(v), 0644))
|
|
|
+ }
|
|
|
+
|
|
|
+ m.ScanFolders()
|
|
|
+
|
|
|
+ count := 0
|
|
|
+ snap := dbSnapshot(t, m, "default")
|
|
|
+ snap.WithHave(protocol.LocalDeviceID, func(i db.FileIntf) bool {
|
|
|
+ count++
|
|
|
+ return true
|
|
|
+ })
|
|
|
+ snap.Release()
|
|
|
+
|
|
|
+ if count != numFiles {
|
|
|
+ t.Errorf("Unexpected count: %d != %d", count, numFiles)
|
|
|
+ }
|
|
|
+
|
|
|
+ // Modify all the files, other than the ones we expect to rename
|
|
|
+ for i := 0; i < numFiles; i++ {
|
|
|
+ if i == 3 || i == 17 || i == 16 || i == 4 {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ v := fmt.Sprintf("%d", i)
|
|
|
+ must(t, writeFile(ffs, v, []byte(v+"-new"), 0644))
|
|
|
+ }
|
|
|
+ // Rename
|
|
|
+ must(t, ffs.Rename("3", "17"))
|
|
|
+ must(t, ffs.Rename("16", "4"))
|
|
|
+
|
|
|
+ // Scan
|
|
|
+ m.ScanFolders()
|
|
|
+
|
|
|
+ // Verify sequence of a appearing is followed by c disappearing.
|
|
|
+ snap = dbSnapshot(t, m, "default")
|
|
|
+ defer snap.Release()
|
|
|
+
|
|
|
+ var firstExpectedSequence int64
|
|
|
+ var secondExpectedSequence int64
|
|
|
+ failed := false
|
|
|
+ snap.WithHaveSequence(0, func(i db.FileIntf) bool {
|
|
|
+ t.Log(i)
|
|
|
+ if i.FileName() == "17" {
|
|
|
+ firstExpectedSequence = i.SequenceNo() + 1
|
|
|
+ }
|
|
|
+ if i.FileName() == "4" {
|
|
|
+ secondExpectedSequence = i.SequenceNo() + 1
|
|
|
+ }
|
|
|
+ if i.FileName() == "3" {
|
|
|
+ failed = i.SequenceNo() != firstExpectedSequence || failed
|
|
|
+ }
|
|
|
+ if i.FileName() == "16" {
|
|
|
+ failed = i.SequenceNo() != secondExpectedSequence || failed
|
|
|
+ }
|
|
|
+ return true
|
|
|
+ })
|
|
|
+ if failed {
|
|
|
+ t.Fail()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func TestBlockListMap(t *testing.T) {
|
|
|
+ wcfg, fcfg := tmpDefaultWrapper()
|
|
|
+ m := setupModel(wcfg)
|
|
|
+ defer cleanupModel(m)
|
|
|
+
|
|
|
+ ffs := fcfg.Filesystem()
|
|
|
+ must(t, writeFile(ffs, "one", []byte("content"), 0644))
|
|
|
+ must(t, writeFile(ffs, "two", []byte("content"), 0644))
|
|
|
+ must(t, writeFile(ffs, "three", []byte("content"), 0644))
|
|
|
+ must(t, writeFile(ffs, "four", []byte("content"), 0644))
|
|
|
+ must(t, writeFile(ffs, "five", []byte("content"), 0644))
|
|
|
+
|
|
|
+ m.ScanFolders()
|
|
|
+
|
|
|
+ snap := dbSnapshot(t, m, "default")
|
|
|
+ defer snap.Release()
|
|
|
+ fi, ok := snap.Get(protocol.LocalDeviceID, "one")
|
|
|
+ if !ok {
|
|
|
+ t.Error("failed to find existing file")
|
|
|
+ }
|
|
|
+ var paths []string
|
|
|
+
|
|
|
+ snap.WithBlocksHash(fi.BlocksHash, func(fi db.FileIntf) bool {
|
|
|
+ paths = append(paths, fi.FileName())
|
|
|
+ return true
|
|
|
+ })
|
|
|
+ snap.Release()
|
|
|
+
|
|
|
+ expected := []string{"one", "two", "three", "four", "five"}
|
|
|
+ if !equalStringsInAnyOrder(paths, expected) {
|
|
|
+ t.Errorf("expected %q got %q", expected, paths)
|
|
|
+ }
|
|
|
+
|
|
|
+ // Fudge the files around
|
|
|
+ // Remove
|
|
|
+ must(t, ffs.Remove("one"))
|
|
|
+
|
|
|
+ // Modify
|
|
|
+ must(t, ffs.Remove("two"))
|
|
|
+ must(t, writeFile(ffs, "two", []byte("mew-content"), 0644))
|
|
|
+
|
|
|
+ // Rename
|
|
|
+ must(t, ffs.Rename("three", "new-three"))
|
|
|
+
|
|
|
+ // Change type
|
|
|
+ must(t, ffs.Remove("four"))
|
|
|
+ must(t, ffs.Mkdir("four", 0644))
|
|
|
+
|
|
|
+ m.ScanFolders()
|
|
|
+
|
|
|
+ // Check we're left with 2 of the 5
|
|
|
+ snap = dbSnapshot(t, m, "default")
|
|
|
+ defer snap.Release()
|
|
|
+
|
|
|
+ paths = paths[:0]
|
|
|
+ snap.WithBlocksHash(fi.BlocksHash, func(fi db.FileIntf) bool {
|
|
|
+ paths = append(paths, fi.FileName())
|
|
|
+ return true
|
|
|
+ })
|
|
|
+ snap.Release()
|
|
|
+
|
|
|
+ expected = []string{"new-three", "five"}
|
|
|
+ if !equalStringsInAnyOrder(paths, expected) {
|
|
|
+ t.Errorf("expected %q got %q", expected, paths)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func equalStringsInAnyOrder(a, b []string) bool {
|
|
|
+ if len(a) != len(b) {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ sort.Strings(a)
|
|
|
+ sort.Strings(b)
|
|
|
+ for i := range a {
|
|
|
+ if a[i] != b[i] {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true
|
|
|
+}
|