This commit is contained in:
@@ -1178,8 +1178,8 @@ func TestReceiveOnlyAccounting(t *testing.T) {
|
||||
if n := s.GlobalSize().Files; n != 3 {
|
||||
t.Fatal("expected 3 global files after local change, not", n)
|
||||
}
|
||||
if n := s.GlobalSize().Bytes; n != 120 {
|
||||
t.Fatal("expected 120 global bytes after local change, not", n)
|
||||
if n := s.GlobalSize().Bytes; n != 30 {
|
||||
t.Fatal("expected 30 global files after local change, not", n)
|
||||
}
|
||||
if n := s.ReceiveOnlyChangedSize().Files; n != 1 {
|
||||
t.Fatal("expected 1 receive only changed file after local change, not", n)
|
||||
@@ -1271,6 +1271,44 @@ func TestRemoteInvalidNotAccounted(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestNeedWithNewerInvalid(t *testing.T) {
|
||||
ldb := db.OpenMemory()
|
||||
|
||||
s := db.NewFileSet("default", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
||||
|
||||
rem0ID := remoteDevice0.Short()
|
||||
rem1ID := remoteDevice1.Short()
|
||||
|
||||
// Initial state: file present on rem0 and rem1, but not locally.
|
||||
file := protocol.FileInfo{Name: "foo"}
|
||||
file.Version = file.Version.Update(rem0ID)
|
||||
s.Update(remoteDevice0, fileList{file})
|
||||
s.Update(remoteDevice1, fileList{file})
|
||||
|
||||
need := needList(s, protocol.LocalDeviceID)
|
||||
if len(need) != 1 {
|
||||
t.Fatal("Locally missing file should be needed")
|
||||
}
|
||||
if !need[0].IsEquivalent(file) {
|
||||
t.Fatalf("Got needed file %v, expected %v", need[0], file)
|
||||
}
|
||||
|
||||
// rem1 sends an invalid file with increased version
|
||||
inv := file
|
||||
inv.Version = inv.Version.Update(rem1ID)
|
||||
inv.RawInvalid = true
|
||||
s.Update(remoteDevice1, fileList{inv})
|
||||
|
||||
// We still have an old file, we need the newest valid file
|
||||
need = needList(s, protocol.LocalDeviceID)
|
||||
if len(need) != 1 {
|
||||
t.Fatal("Locally missing file should be needed regardless of invalid files")
|
||||
}
|
||||
if !need[0].IsEquivalent(file) {
|
||||
t.Fatalf("Got needed file %v, expected %v", need[0], file)
|
||||
}
|
||||
}
|
||||
|
||||
func replace(fs *db.FileSet, device protocol.DeviceID, files []protocol.FileInfo) {
|
||||
fs.Drop(device)
|
||||
fs.Update(device, files)
|
||||
|
||||
@@ -12,6 +12,7 @@ package db
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
@@ -150,7 +151,7 @@ func (vl VersionList) String() string {
|
||||
b.WriteString(", ")
|
||||
}
|
||||
copy(id[:], v.Device)
|
||||
fmt.Fprintf(&b, "{%v, %v, %v}", v.Version, id, v.Invalid)
|
||||
fmt.Fprintf(&b, "{%v, %v}", v.Version, id)
|
||||
}
|
||||
b.WriteString("}")
|
||||
return b.String()
|
||||
@@ -175,12 +176,15 @@ func (vl VersionList) update(folder, device []byte, file protocol.FileInfo, db *
|
||||
Version: file.Version,
|
||||
Invalid: file.IsInvalid(),
|
||||
}
|
||||
for i, v := range vl.Versions {
|
||||
switch v.Version.Compare(file.Version) {
|
||||
i := 0
|
||||
if nv.Invalid {
|
||||
i = sort.Search(len(vl.Versions), func(j int) bool {
|
||||
return vl.Versions[j].Invalid
|
||||
})
|
||||
}
|
||||
for ; i < len(vl.Versions); i++ {
|
||||
switch vl.Versions[i].Version.Compare(file.Version) {
|
||||
case protocol.Equal:
|
||||
if nv.Invalid {
|
||||
continue
|
||||
}
|
||||
fallthrough
|
||||
|
||||
case protocol.Lesser:
|
||||
@@ -198,7 +202,7 @@ func (vl VersionList) update(folder, device []byte, file protocol.FileInfo, db *
|
||||
// to determine the winner.)
|
||||
//
|
||||
// A surprise missing file entry here is counted as a win for us.
|
||||
if of, ok := db.getFile(db.keyer.GenerateDeviceFileKey(nil, folder, v.Device, []byte(file.Name))); !ok || file.WinsConflict(of) {
|
||||
if of, ok := db.getFile(db.keyer.GenerateDeviceFileKey(nil, folder, vl.Versions[i].Device, []byte(file.Name))); !ok || file.WinsConflict(of) {
|
||||
vl = vl.insertAt(i, nv)
|
||||
return vl, removedFV, removedAt, i
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ func need(global FileIntf, haveLocal bool, localVersion protocol.Vector) bool {
|
||||
return false
|
||||
}
|
||||
// We don't need the global file if we already have the same version.
|
||||
if haveLocal && localVersion.Equal(global.FileVersion()) {
|
||||
if haveLocal && localVersion.GreaterEqual(global.FileVersion()) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
||||
Reference in New Issue
Block a user