From 69f2c26d50cc54d2b62aa70f4b0391eee2dd4159 Mon Sep 17 00:00:00 2001 From: Simon Frei Date: Tue, 27 Mar 2018 22:24:20 +0200 Subject: [PATCH] lib/scanner, lib/model: Actually assign version when un-ignoring (fixes #4841) (#4842) This fixes a mistake introduced in #4750 and #4776 and is relevant to v0.14.46-rc1 --- lib/model/model.go | 2 +- lib/model/requests_test.go | 39 ++++++++++++++++++++++++++++ lib/scanner/walk.go | 6 ++--- lib/scanner/walk_test.go | 53 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 96 insertions(+), 4 deletions(-) diff --git a/lib/model/model.go b/lib/model/model.go index 79bc40785..8a2c05c3f 100644 --- a/lib/model/model.go +++ b/lib/model/model.go @@ -2076,7 +2076,7 @@ func (m *Model) internalScanFolderSubdirs(ctx context.Context, folder string, su // other existing versions, which will be resolved // by the normal pulling mechanisms. if f.IsInvalid() { - nf.Version.DropOthers(m.shortID) + nf.Version = nf.Version.DropOthers(m.shortID) } batch = append(batch, nf) diff --git a/lib/model/requests_test.go b/lib/model/requests_test.go index ea3e10e0e..0a79ad547 100644 --- a/lib/model/requests_test.go +++ b/lib/model/requests_test.go @@ -425,6 +425,45 @@ func pullInvalidIgnored(t *testing.T, ft config.FolderType) { } } +func TestIssue4841(t *testing.T) { + m, fc, tmpDir := setupModelWithConnection() + defer m.Stop() + defer os.RemoveAll(tmpDir) + + received := make(chan protocol.FileInfo) + fc.mut.Lock() + fc.indexFn = func(folder string, fs []protocol.FileInfo) { + if len(fs) != 1 { + t.Fatalf("Sent index with %d files, should be 1", len(fs)) + } + if fs[0].Name != "foo" { + t.Fatalf(`Sent index with file %v, should be "foo"`, fs[0].Name) + } + received <- fs[0] + return + } + fc.mut.Unlock() + + // Setup file from remote that was ignored locally + m.updateLocals(defaultFolderConfig.ID, []protocol.FileInfo{{ + Name: "foo", + Type: protocol.FileInfoTypeFile, + Invalid: true, + Version: protocol.Vector{}.Update(device2.Short()), + }}) + <-received + + // Scan without ignore patterns with "foo" not existing locally + if err := m.ScanFolder("default"); err != nil { + t.Fatal("Failed scanning:", err) + } + + f := <-received + if expected := (protocol.Vector{}.Update(device1.Short())); !f.Version.Equal(expected) { + t.Errorf("Got Version == %v, expected %v", f.Version, expected) + } +} + func setupModelWithConnection() (*Model, *fakeConnection, string) { tmpDir := createTmpDir() cfg := defaultCfgWrapper.RawCopy() diff --git a/lib/scanner/walk.go b/lib/scanner/walk.go index 1794b15c7..6f958e9dc 100644 --- a/lib/scanner/walk.go +++ b/lib/scanner/walk.go @@ -308,7 +308,7 @@ func (w *walker) walkRegular(ctx context.Context, relPath string, info fs.FileIn // currently have. Keeping only our local counter makes sure we are in // conflict with any other existing versions, which will be resolved by // the normal pulling mechanisms. - f.Version.DropOthers(w.ShortID) + f.Version = f.Version.DropOthers(w.ShortID) } l.Debugln("rescan:", cf, info.ModTime().Unix(), info.Mode()&fs.ModePerm) } @@ -347,7 +347,7 @@ func (w *walker) walkDir(ctx context.Context, relPath string, info fs.FileInfo, // currently have. Keeping only our local counter makes sure we are in // conflict with any other existing versions, which will be resolved by // the normal pulling mechanisms. - f.Version.DropOthers(w.ShortID) + f.Version = f.Version.DropOthers(w.ShortID) } } @@ -402,7 +402,7 @@ func (w *walker) walkSymlink(ctx context.Context, relPath string, dchan chan pro // currently have. Keeping only our local counter makes sure we are in // conflict with any other existing versions, which will be resolved by // the normal pulling mechanisms. - f.Version.DropOthers(w.ShortID) + f.Version = f.Version.DropOthers(w.ShortID) } } diff --git a/lib/scanner/walk_test.go b/lib/scanner/walk_test.go index 3d9999843..33e2308f3 100644 --- a/lib/scanner/walk_test.go +++ b/lib/scanner/walk_test.go @@ -522,6 +522,52 @@ func TestIssue4799(t *testing.T) { } } +func TestIssue4841(t *testing.T) { + tmp, err := ioutil.TempDir("", "") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmp) + + fs := fs.NewFilesystem(fs.FilesystemTypeBasic, tmp) + + fd, err := fs.Create("foo") + if err != nil { + panic(err) + } + fd.Close() + + fchan := Walk(context.TODO(), Config{ + Filesystem: fs, + Subs: nil, + BlockSize: 128 * 1024, + AutoNormalize: true, + Hashers: 2, + CurrentFiler: fakeCurrentFiler{ + "foo": { + Name: "foo", + Type: protocol.FileInfoTypeFile, + Invalid: true, + Version: protocol.Vector{}.Update(1), + }, + }, + ShortID: protocol.LocalDeviceID.Short(), + }) + + var files []protocol.FileInfo + for f := range fchan { + files = append(files, f) + } + sort.Sort(fileList(files)) + + if len(files) != 1 { + t.Fatalf("Expected 1 file, got %d: %v", len(files), files) + } + if expected := (protocol.Vector{}.Update(protocol.LocalDeviceID.Short())); !files[0].Version.Equal(expected) { + t.Fatalf("Expected Version == %v, got %v", expected, files[0].Version) + } +} + // Verify returns nil or an error describing the mismatch between the block // list and actual reader contents func verify(r io.Reader, blocksize int, blocks []protocol.BlockInfo) error { @@ -553,3 +599,10 @@ func verify(r io.Reader, blocksize int, blocks []protocol.BlockInfo) error { return nil } + +type fakeCurrentFiler map[string]protocol.FileInfo + +func (fcf fakeCurrentFiler) CurrentFile(name string) (protocol.FileInfo, bool) { + f, ok := fcf[name] + return f, ok +}