Browse Source

lib/protocol: Invalid files should always lose (#4747)

Simon Frei 8 years ago
parent
commit
4955297bf6
3 changed files with 10 additions and 0 deletions
  1. 4 0
      lib/db/set_test.go
  2. 5 0
      lib/protocol/bep_extensions.go
  3. 1 0
      lib/protocol/conflict_test.go

+ 4 - 0
lib/db/set_test.go

@@ -606,6 +606,7 @@ func TestGlobalNeedWithInvalid(t *testing.T) {
 		protocol.FileInfo{Name: "a", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Blocks: genBlocks(4)},
 		protocol.FileInfo{Name: "b", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Invalid: true},
 		protocol.FileInfo{Name: "c", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Blocks: genBlocks(4)},
+		protocol.FileInfo{Name: "d", Version: protocol.Vector{Counters: []protocol.Counter{{ID: remoteDevice0.Short(), Value: 1002}}}},
 	}
 	replace(s, remoteDevice0, rem0)
 
@@ -613,6 +614,7 @@ func TestGlobalNeedWithInvalid(t *testing.T) {
 		protocol.FileInfo{Name: "a", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Blocks: genBlocks(4)},
 		protocol.FileInfo{Name: "b", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Blocks: genBlocks(4)},
 		protocol.FileInfo{Name: "c", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Invalid: true},
+		protocol.FileInfo{Name: "d", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Invalid: true, ModifiedS: 10},
 	}
 	replace(s, remoteDevice1, rem1)
 
@@ -621,6 +623,8 @@ func TestGlobalNeedWithInvalid(t *testing.T) {
 		protocol.FileInfo{Name: "a", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Blocks: genBlocks(4)},
 		protocol.FileInfo{Name: "b", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Blocks: genBlocks(4)},
 		protocol.FileInfo{Name: "c", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}, Blocks: genBlocks(4)},
+		// in conflict and older, but still wins as the other is invalid
+		protocol.FileInfo{Name: "d", Version: protocol.Vector{Counters: []protocol.Counter{{ID: remoteDevice0.Short(), Value: 1002}}}},
 	}
 
 	need := fileList(needList(s, protocol.LocalDeviceID))

+ 5 - 0
lib/protocol/bep_extensions.go

@@ -95,6 +95,11 @@ func (f FileInfo) SequenceNo() int64 {
 // WinsConflict returns true if "f" is the one to choose when it is in
 // conflict with "other".
 func (f FileInfo) WinsConflict(other FileInfo) bool {
+	// If only one of the files is invalid, that one loses
+	if f.IsInvalid() != other.IsInvalid() {
+		return !f.IsInvalid()
+	}
+
 	// If a modification is in conflict with a delete, we pick the
 	// modification.
 	if !f.IsDeleted() && other.IsDeleted() {

+ 1 - 0
lib/protocol/conflict_test.go

@@ -9,6 +9,7 @@ func TestWinsConflict(t *testing.T) {
 		// The first should always win over the second
 		{{ModifiedS: 42}, {ModifiedS: 41}},
 		{{ModifiedS: 41}, {ModifiedS: 42, Deleted: true}},
+		{{Deleted: true}, {ModifiedS: 10, Invalid: true}},
 		{{ModifiedS: 41, Version: Vector{[]Counter{{42, 2}, {43, 1}}}}, {ModifiedS: 41, Version: Vector{[]Counter{{42, 1}, {43, 2}}}}},
 	}