lib: Get rid of buggy filesystem wrapping (#8257)

This commit is contained in:
Simon Frei
2022-04-10 20:55:05 +02:00
committed by GitHub
parent 9b09bcc5f1
commit db72579f0e
26 changed files with 226 additions and 189 deletions
+2 -2
View File
@@ -457,7 +457,7 @@ func TestIssue1262(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
actual := cfg.Folders()["test"].Filesystem().URI() actual := cfg.Folders()["test"].Filesystem(nil).URI()
expected := `e:\` expected := `e:\`
if actual != expected { if actual != expected {
@@ -494,7 +494,7 @@ func TestFolderPath(t *testing.T) {
Path: "~/tmp", Path: "~/tmp",
} }
realPath := folder.Filesystem().URI() realPath := folder.Filesystem(nil).URI()
if !filepath.IsAbs(realPath) { if !filepath.IsAbs(realPath) {
t.Error(realPath, "should be absolute") t.Error(realPath, "should be absolute")
} }
+18 -12
View File
@@ -16,6 +16,7 @@ import (
"github.com/shirou/gopsutil/v3/disk" "github.com/shirou/gopsutil/v3/disk"
"github.com/syncthing/syncthing/lib/db"
"github.com/syncthing/syncthing/lib/fs" "github.com/syncthing/syncthing/lib/fs"
"github.com/syncthing/syncthing/lib/protocol" "github.com/syncthing/syncthing/lib/protocol"
"github.com/syncthing/syncthing/lib/util" "github.com/syncthing/syncthing/lib/util"
@@ -42,24 +43,29 @@ func (f FolderConfiguration) Copy() FolderConfiguration {
return c return c
} }
func (f FolderConfiguration) Filesystem() fs.Filesystem { // Filesystem creates a filesystem for the path and options of this folder.
// The fset parameter may be nil, in which case no mtime handling on top of
// the fileystem is provided.
func (f FolderConfiguration) Filesystem(fset *db.FileSet) fs.Filesystem {
// This is intentionally not a pointer method, because things like // This is intentionally not a pointer method, because things like
// cfg.Folders["default"].Filesystem() should be valid. // cfg.Folders["default"].Filesystem(nil) should be valid.
var opts []fs.Option opts := make([]fs.Option, 0, 3)
if f.FilesystemType == fs.FilesystemTypeBasic && f.JunctionsAsDirs { if f.FilesystemType == fs.FilesystemTypeBasic && f.JunctionsAsDirs {
opts = append(opts, new(fs.OptionJunctionsAsDirs)) opts = append(opts, new(fs.OptionJunctionsAsDirs))
} }
filesystem := fs.NewFilesystem(f.FilesystemType, f.Path, opts...)
if !f.CaseSensitiveFS { if !f.CaseSensitiveFS {
filesystem = fs.NewCaseFilesystem(filesystem) opts = append(opts, new(fs.OptionDetectCaseConflicts))
} }
return filesystem if fset != nil {
opts = append(opts, fset.MtimeOption())
}
return fs.NewFilesystem(f.FilesystemType, f.Path, opts...)
} }
func (f FolderConfiguration) ModTimeWindow() time.Duration { func (f FolderConfiguration) ModTimeWindow() time.Duration {
dur := time.Duration(f.RawModTimeWindowS) * time.Second dur := time.Duration(f.RawModTimeWindowS) * time.Second
if f.RawModTimeWindowS < 1 && runtime.GOOS == "android" { if f.RawModTimeWindowS < 1 && runtime.GOOS == "android" {
if usage, err := disk.Usage(f.Filesystem().URI()); err != nil { if usage, err := disk.Usage(f.Filesystem(nil).URI()); err != nil {
dur = 2 * time.Second dur = 2 * time.Second
l.Debugf(`Detecting FS at "%v" on android: Setting mtime window to 2s: err == "%v"`, f.Path, err) l.Debugf(`Detecting FS at "%v" on android: Setting mtime window to 2s: err == "%v"`, f.Path, err)
} else if strings.HasPrefix(strings.ToLower(usage.Fstype), "ext2") || strings.HasPrefix(strings.ToLower(usage.Fstype), "ext3") || strings.HasPrefix(strings.ToLower(usage.Fstype), "ext4") { } else if strings.HasPrefix(strings.ToLower(usage.Fstype), "ext2") || strings.HasPrefix(strings.ToLower(usage.Fstype), "ext3") || strings.HasPrefix(strings.ToLower(usage.Fstype), "ext4") {
@@ -89,7 +95,7 @@ func (f *FolderConfiguration) CreateMarker() error {
// begin with. // begin with.
permBits = 0700 permBits = 0700
} }
fs := f.Filesystem() fs := f.Filesystem(nil)
err := fs.Mkdir(DefaultMarkerName, permBits) err := fs.Mkdir(DefaultMarkerName, permBits)
if err != nil { if err != nil {
return err return err
@@ -106,7 +112,7 @@ func (f *FolderConfiguration) CreateMarker() error {
// CheckPath returns nil if the folder root exists and contains the marker file // CheckPath returns nil if the folder root exists and contains the marker file
func (f *FolderConfiguration) CheckPath() error { func (f *FolderConfiguration) CheckPath() error {
fi, err := f.Filesystem().Stat(".") fi, err := f.Filesystem(nil).Stat(".")
if err != nil { if err != nil {
if !fs.IsNotExist(err) { if !fs.IsNotExist(err) {
return err return err
@@ -124,7 +130,7 @@ func (f *FolderConfiguration) CheckPath() error {
return ErrPathNotDirectory return ErrPathNotDirectory
} }
_, err = f.Filesystem().Stat(f.MarkerName) _, err = f.Filesystem(nil).Stat(f.MarkerName)
if err != nil { if err != nil {
if !fs.IsNotExist(err) { if !fs.IsNotExist(err) {
return err return err
@@ -145,7 +151,7 @@ func (f *FolderConfiguration) CreateRoot() (err error) {
permBits = 0700 permBits = 0700
} }
filesystem := f.Filesystem() filesystem := f.Filesystem(nil)
if _, err = filesystem.Stat("."); fs.IsNotExist(err) { if _, err = filesystem.Stat("."); fs.IsNotExist(err) {
err = filesystem.MkdirAll(".", permBits) err = filesystem.MkdirAll(".", permBits)
@@ -256,7 +262,7 @@ func (f *FolderConfiguration) CheckAvailableSpace(req uint64) error {
if val <= 0 { if val <= 0 {
return nil return nil
} }
fs := f.Filesystem() fs := f.Filesystem(nil)
usage, err := fs.Usage(".") usage, err := fs.Usage(".")
if err != nil { if err != nil {
return nil return nil
+4 -4
View File
@@ -199,7 +199,7 @@ func migrateToConfigV23(cfg *Configuration) {
// marker name in later versions. // marker name in later versions.
for i := range cfg.Folders { for i := range cfg.Folders {
fs := cfg.Folders[i].Filesystem() fs := cfg.Folders[i].Filesystem(nil)
// Invalid config posted, or tests. // Invalid config posted, or tests.
if fs == nil { if fs == nil {
continue continue
@@ -235,18 +235,18 @@ func migrateToConfigV21(cfg *Configuration) {
switch folder.Versioning.Type { switch folder.Versioning.Type {
case "simple", "trashcan": case "simple", "trashcan":
// Clean out symlinks in the known place // Clean out symlinks in the known place
cleanSymlinks(folder.Filesystem(), ".stversions") cleanSymlinks(folder.Filesystem(nil), ".stversions")
case "staggered": case "staggered":
versionDir := folder.Versioning.Params["versionsPath"] versionDir := folder.Versioning.Params["versionsPath"]
if versionDir == "" { if versionDir == "" {
// default place // default place
cleanSymlinks(folder.Filesystem(), ".stversions") cleanSymlinks(folder.Filesystem(nil), ".stversions")
} else if filepath.IsAbs(versionDir) { } else if filepath.IsAbs(versionDir) {
// absolute // absolute
cleanSymlinks(fs.NewFilesystem(fs.FilesystemTypeBasic, versionDir), ".") cleanSymlinks(fs.NewFilesystem(fs.FilesystemTypeBasic, versionDir), ".")
} else { } else {
// relative to folder // relative to folder
cleanSymlinks(folder.Filesystem(), versionDir) cleanSymlinks(folder.Filesystem(nil), versionDir)
} }
} }
} }
+3 -3
View File
@@ -403,8 +403,8 @@ func (s *FileSet) SetIndexID(device protocol.DeviceID, id protocol.IndexID) {
} }
} }
func (s *FileSet) MtimeFS(filesystem fs.Filesystem) fs.Filesystem { func (s *FileSet) MtimeOption() fs.Option {
opStr := fmt.Sprintf("%s MtimeFS()", s.folder) opStr := fmt.Sprintf("%s MtimeOption()", s.folder)
l.Debugf(opStr) l.Debugf(opStr)
prefix, err := s.db.keyer.GenerateMtimesKey(nil, []byte(s.folder)) prefix, err := s.db.keyer.GenerateMtimesKey(nil, []byte(s.folder))
if backend.IsClosed(err) { if backend.IsClosed(err) {
@@ -413,7 +413,7 @@ func (s *FileSet) MtimeFS(filesystem fs.Filesystem) fs.Filesystem {
fatalError(err, opStr, s.db) fatalError(err, opStr, s.db)
} }
kv := NewNamespacedKV(s.db, string(prefix)) kv := NewNamespacedKV(s.db, string(prefix))
return fs.NewMtimeFS(filesystem, kv) return fs.NewMtimeOption(kv)
} }
func (s *FileSet) ListDevices() []protocol.DeviceID { func (s *FileSet) ListDevices() []protocol.DeviceID {
+2 -1
View File
@@ -27,12 +27,13 @@ var (
type OptionJunctionsAsDirs struct{} type OptionJunctionsAsDirs struct{}
func (o *OptionJunctionsAsDirs) apply(fs Filesystem) { func (o *OptionJunctionsAsDirs) apply(fs Filesystem) Filesystem {
if basic, ok := fs.(*BasicFilesystem); !ok { if basic, ok := fs.(*BasicFilesystem); !ok {
l.Warnln("WithJunctionsAsDirs must only be used with FilesystemTypeBasic") l.Warnln("WithJunctionsAsDirs must only be used with FilesystemTypeBasic")
} else { } else {
basic.junctionsAsDirs = true basic.junctionsAsDirs = true
} }
return fs
} }
func (o *OptionJunctionsAsDirs) String() string { func (o *OptionJunctionsAsDirs) String() string {
+16 -10
View File
@@ -123,21 +123,27 @@ func (r *caseFilesystemRegistry) cleaner() {
var globalCaseFilesystemRegistry = caseFilesystemRegistry{fss: make(map[fskey]*caseFilesystem)} var globalCaseFilesystemRegistry = caseFilesystemRegistry{fss: make(map[fskey]*caseFilesystem)}
// caseFilesystem is a BasicFilesystem with additional checks to make a // OptionDetectCaseConflicts ensures that the potentially case-insensitive filesystem
// potentially case insensitive underlying FS behave like it's case-sensitive.
type caseFilesystem struct {
Filesystem
realCaser
}
// NewCaseFilesystem ensures that the given, potentially case-insensitive filesystem
// behaves like a case-sensitive filesystem. Meaning that it takes into account // behaves like a case-sensitive filesystem. Meaning that it takes into account
// the real casing of a path and returns ErrCaseConflict if the given path differs // the real casing of a path and returns ErrCaseConflict if the given path differs
// from the real path. It is safe to use with any filesystem, i.e. also a // from the real path. It is safe to use with any filesystem, i.e. also a
// case-sensitive one. However it will add some overhead and thus shouldn't be // case-sensitive one. However it will add some overhead and thus shouldn't be
// used if the filesystem is known to already behave case-sensitively. // used if the filesystem is known to already behave case-sensitively.
func NewCaseFilesystem(fs Filesystem) Filesystem { type OptionDetectCaseConflicts struct{}
return wrapFilesystem(fs, globalCaseFilesystemRegistry.get)
func (o *OptionDetectCaseConflicts) apply(fs Filesystem) Filesystem {
return globalCaseFilesystemRegistry.get(fs)
}
func (o *OptionDetectCaseConflicts) String() string {
return "detectCaseConflicts"
}
// caseFilesystem is a BasicFilesystem with additional checks to make a
// potentially case insensitive underlying FS behave like it's case-sensitive.
type caseFilesystem struct {
Filesystem
realCaser
} }
func (f *caseFilesystem) Chmod(name string, mode FileMode) error { func (f *caseFilesystem) Chmod(name string, mode FileMode) error {
+7 -3
View File
@@ -34,8 +34,12 @@ func TestRealCase(t *testing.T) {
}) })
} }
func newCaseFilesystem(fsys Filesystem) *caseFilesystem {
return globalCaseFilesystemRegistry.get(fsys).(*caseFilesystem)
}
func testRealCase(t *testing.T, fsys Filesystem) { func testRealCase(t *testing.T, fsys Filesystem) {
testFs := NewCaseFilesystem(fsys).(*caseFilesystem) testFs := newCaseFilesystem(fsys)
comps := []string{"Foo", "bar", "BAZ", "bAs"} comps := []string{"Foo", "bar", "BAZ", "bAs"}
path := filepath.Join(comps...) path := filepath.Join(comps...)
testFs.MkdirAll(filepath.Join(comps[:len(comps)-1]...), 0777) testFs.MkdirAll(filepath.Join(comps[:len(comps)-1]...), 0777)
@@ -86,7 +90,7 @@ func TestRealCaseSensitive(t *testing.T) {
} }
func testRealCaseSensitive(t *testing.T, fsys Filesystem) { func testRealCaseSensitive(t *testing.T, fsys Filesystem) {
testFs := NewCaseFilesystem(fsys).(*caseFilesystem) testFs := newCaseFilesystem(fsys)
names := make([]string, 2) names := make([]string, 2)
names[0] = "foo" names[0] = "foo"
@@ -139,7 +143,7 @@ func testCaseFSStat(t *testing.T, fsys Filesystem) {
sensitive = false sensitive = false
} }
testFs := NewCaseFilesystem(fsys) testFs := newCaseFilesystem(fsys)
_, err = testFs.Stat("FOO") _, err = testFs.Stat("FOO")
if sensitive { if sensitive {
if IsNotExist(err) { if IsNotExist(err) {
+31 -16
View File
@@ -202,10 +202,29 @@ var IsPathSeparator = os.IsPathSeparator
// representation of those must be part of the returned string. // representation of those must be part of the returned string.
type Option interface { type Option interface {
String() string String() string
apply(Filesystem) apply(Filesystem) Filesystem
} }
func NewFilesystem(fsType FilesystemType, uri string, opts ...Option) Filesystem { func NewFilesystem(fsType FilesystemType, uri string, opts ...Option) Filesystem {
var caseOpt Option
var mtimeOpt Option
i := 0
for _, opt := range opts {
if caseOpt != nil && mtimeOpt != nil {
break
}
switch opt.(type) {
case *OptionDetectCaseConflicts:
caseOpt = opt
case *optionMtime:
mtimeOpt = opt
default:
opts[i] = opt
i++
}
}
opts = opts[:i]
var fs Filesystem var fs Filesystem
switch fsType { switch fsType {
case FilesystemTypeBasic: case FilesystemTypeBasic:
@@ -221,6 +240,17 @@ func NewFilesystem(fsType FilesystemType, uri string, opts ...Option) Filesystem
} }
} }
// Case handling is the innermost, as any filesystem calls by wrappers should be case-resolved
if caseOpt != nil {
fs = caseOpt.apply(fs)
}
// mtime handling should happen inside walking, as filesystem calls while
// walking should be mtime-resolved too
if mtimeOpt != nil {
fs = mtimeOpt.apply(fs)
}
if l.ShouldDebug("walkfs") { if l.ShouldDebug("walkfs") {
return NewWalkFilesystem(&logFilesystem{fs}) return NewWalkFilesystem(&logFilesystem{fs})
} }
@@ -289,21 +319,6 @@ func Canonicalize(file string) (string, error) {
return file, nil return file, nil
} }
// wrapFilesystem should always be used when wrapping a Filesystem.
// It ensures proper wrapping order, which right now means:
// `logFilesystem` needs to be the outermost wrapper for caller lookup.
func wrapFilesystem(fs Filesystem, wrapFn func(Filesystem) Filesystem) Filesystem {
logFs, ok := fs.(*logFilesystem)
if ok {
fs = logFs.Filesystem
}
fs = wrapFn(fs)
if ok {
fs = &logFilesystem{fs}
}
return fs
}
// unwrapFilesystem removes "wrapping" filesystems to expose the filesystem of the requested wrapperType, if it exists. // unwrapFilesystem removes "wrapping" filesystems to expose the filesystem of the requested wrapperType, if it exists.
func unwrapFilesystem(fs Filesystem, wrapperType filesystemWrapperType) (Filesystem, bool) { func unwrapFilesystem(fs Filesystem, wrapperType filesystemWrapperType) (Filesystem, bool) {
var ok bool var ok bool
+28 -33
View File
@@ -33,20 +33,34 @@ func WithCaseInsensitivity(v bool) MtimeFSOption {
} }
} }
// NewMtimeFS returns a filesystem with nanosecond mtime precision, regardless type optionMtime struct {
// of what shenanigans the underlying filesystem gets up to. db database
func NewMtimeFS(fs Filesystem, db database, options ...MtimeFSOption) Filesystem { options []MtimeFSOption
return wrapFilesystem(fs, func(underlying Filesystem) Filesystem { }
f := &mtimeFS{
Filesystem: underlying, // NewMtimeOption makes any filesystem provide nanosecond mtime precision,
chtimes: underlying.Chtimes, // for mocking it out in the tests // regardless of what shenanigans the underlying filesystem gets up to.
db: db, func NewMtimeOption(db database, options ...MtimeFSOption) Option {
} return &optionMtime{
for _, opt := range options { db: db,
opt(f) options: options,
} }
return f }
})
func (o *optionMtime) apply(fs Filesystem) Filesystem {
f := &mtimeFS{
Filesystem: fs,
chtimes: fs.Chtimes, // for mocking it out in the tests
db: o.db,
}
for _, opt := range o.options {
opt(f)
}
return f
}
func (_ *optionMtime) String() string {
return "mtime"
} }
func (f *mtimeFS) Chtimes(name string, atime, mtime time.Time) error { func (f *mtimeFS) Chtimes(name string, atime, mtime time.Time) error {
@@ -104,25 +118,6 @@ func (f *mtimeFS) Lstat(name string) (FileInfo, error) {
return info, nil return info, nil
} }
func (f *mtimeFS) Walk(root string, walkFn WalkFunc) error {
return f.Filesystem.Walk(root, func(path string, info FileInfo, err error) error {
if info != nil {
mtimeMapping, loadErr := f.load(path)
if loadErr != nil && err == nil {
// The iterator gets to deal with the error
err = loadErr
}
if mtimeMapping.Real == info.ModTime() {
info = mtimeFileInfo{
FileInfo: info,
mtime: mtimeMapping.Virtual,
}
}
}
return walkFn(path, info, err)
})
}
func (f *mtimeFS) Create(name string) (File, error) { func (f *mtimeFS) Create(name string) (File, error) {
fd, err := f.Filesystem.Create(name) fd, err := f.Filesystem.Create(name)
if err != nil { if err != nil {
+16 -10
View File
@@ -26,7 +26,7 @@ func TestMtimeFS(t *testing.T) {
// a random time with nanosecond precision // a random time with nanosecond precision
testTime := time.Unix(1234567890, 123456789) testTime := time.Unix(1234567890, 123456789)
mtimefs := newMtimeFS(newBasicFilesystem("."), make(mapStore)) mtimefs := newMtimeFS(".", make(mapStore))
// Do one Chtimes call that will go through to the normal filesystem // Do one Chtimes call that will go through to the normal filesystem
mtimefs.chtimes = os.Chtimes mtimefs.chtimes = os.Chtimes
@@ -88,8 +88,8 @@ func TestMtimeFSWalk(t *testing.T) {
} }
defer func() { _ = os.RemoveAll(dir) }() defer func() { _ = os.RemoveAll(dir) }()
underlying := NewFilesystem(FilesystemTypeBasic, dir) mtimefs, walkFs := newMtimeFSWithWalk(dir, make(mapStore))
mtimefs := newMtimeFS(underlying, make(mapStore)) underlying := mtimefs.Filesystem
mtimefs.chtimes = failChtimes mtimefs.chtimes = failChtimes
if err := os.WriteFile(filepath.Join(dir, "file"), []byte("hello"), 0644); err != nil { if err := os.WriteFile(filepath.Join(dir, "file"), []byte("hello"), 0644); err != nil {
@@ -120,7 +120,7 @@ func TestMtimeFSWalk(t *testing.T) {
} }
found := false found := false
_ = mtimefs.Walk("", func(path string, info FileInfo, err error) error { _ = walkFs.Walk("", func(path string, info FileInfo, err error) error {
if path == "file" { if path == "file" {
found = true found = true
if !info.ModTime().Equal(newTime) { if !info.ModTime().Equal(newTime) {
@@ -142,8 +142,8 @@ func TestMtimeFSOpen(t *testing.T) {
} }
defer func() { _ = os.RemoveAll(dir) }() defer func() { _ = os.RemoveAll(dir) }()
underlying := NewFilesystem(FilesystemTypeBasic, dir) mtimefs := newMtimeFS(dir, make(mapStore))
mtimefs := newMtimeFS(underlying, make(mapStore)) underlying := mtimefs.Filesystem
mtimefs.chtimes = failChtimes mtimefs.chtimes = failChtimes
if err := os.WriteFile(filepath.Join(dir, "file"), []byte("hello"), 0644); err != nil { if err := os.WriteFile(filepath.Join(dir, "file"), []byte("hello"), 0644); err != nil {
@@ -222,12 +222,12 @@ func TestMtimeFSInsensitive(t *testing.T) {
// The test should fail with a case sensitive mtimefs // The test should fail with a case sensitive mtimefs
t.Run("with case sensitive mtimefs", func(t *testing.T) { t.Run("with case sensitive mtimefs", func(t *testing.T) {
theTest(t, newMtimeFS(newBasicFilesystem("."), make(mapStore)), false) theTest(t, newMtimeFS(".", make(mapStore)), false)
}) })
// And succeed with a case insensitive one. // And succeed with a case insensitive one.
t.Run("with case insensitive mtimefs", func(t *testing.T) { t.Run("with case insensitive mtimefs", func(t *testing.T) {
theTest(t, newMtimeFS(newBasicFilesystem("."), make(mapStore), WithCaseInsensitivity(true)), true) theTest(t, newMtimeFS(".", make(mapStore), WithCaseInsensitivity(true)), true)
}) })
} }
@@ -261,6 +261,12 @@ func evilChtimes(name string, mtime, atime time.Time) error {
return os.Chtimes(name, mtime.Add(300*time.Hour).Truncate(time.Hour), atime.Add(300*time.Hour).Truncate(time.Hour)) return os.Chtimes(name, mtime.Add(300*time.Hour).Truncate(time.Hour), atime.Add(300*time.Hour).Truncate(time.Hour))
} }
func newMtimeFS(fs Filesystem, db database, options ...MtimeFSOption) *mtimeFS { func newMtimeFS(path string, db database, options ...MtimeFSOption) *mtimeFS {
return NewMtimeFS(fs, db, options...).(*mtimeFS) mtimefs, _ := newMtimeFSWithWalk(path, db, options...)
return mtimefs
}
func newMtimeFSWithWalk(path string, db database, options ...MtimeFSOption) (*mtimeFS, *walkFilesystem) {
wfs := NewFilesystem(FilesystemTypeBasic, path, NewMtimeOption(db, options...)).(*walkFilesystem)
return wfs.Filesystem.(*mtimeFS), wfs
} }
+2 -2
View File
@@ -108,7 +108,7 @@ func newFolder(model *model, fset *db.FileSet, ignores *ignore.Matcher, cfg conf
shortID: model.shortID, shortID: model.shortID,
fset: fset, fset: fset,
ignores: ignores, ignores: ignores,
mtimefs: fset.MtimeFS(cfg.Filesystem()), mtimefs: cfg.Filesystem(fset),
modTimeWindow: cfg.ModTimeWindow(), modTimeWindow: cfg.ModTimeWindow(),
done: make(chan struct{}), done: make(chan struct{}),
@@ -1001,7 +1001,7 @@ func (f *folder) monitorWatch(ctx context.Context) {
for { for {
select { select {
case <-failTimer.C: case <-failTimer.C:
eventChan, errChan, err = f.Filesystem().Watch(".", f.ignores, ctx, f.IgnorePerms) eventChan, errChan, err = f.mtimefs.Watch(".", f.ignores, ctx, f.IgnorePerms)
// We do this once per minute initially increased to // We do this once per minute initially increased to
// max one hour in case of repeat failures. // max one hour in case of repeat failures.
f.scanOnWatchErr() f.scanOnWatchErr()
+6 -6
View File
@@ -28,7 +28,7 @@ func TestRecvOnlyRevertDeletes(t *testing.T) {
m, f, wcfgCancel := setupROFolder(t) m, f, wcfgCancel := setupROFolder(t)
defer wcfgCancel() defer wcfgCancel()
ffs := f.Filesystem() ffs := f.Filesystem(nil)
defer cleanupModel(m) defer cleanupModel(m)
addFakeConn(m, device1, f.ID) addFakeConn(m, device1, f.ID)
@@ -110,7 +110,7 @@ func TestRecvOnlyRevertNeeds(t *testing.T) {
m, f, wcfgCancel := setupROFolder(t) m, f, wcfgCancel := setupROFolder(t)
defer wcfgCancel() defer wcfgCancel()
ffs := f.Filesystem() ffs := f.Filesystem(nil)
defer cleanupModel(m) defer cleanupModel(m)
addFakeConn(m, device1, f.ID) addFakeConn(m, device1, f.ID)
@@ -200,7 +200,7 @@ func TestRecvOnlyUndoChanges(t *testing.T) {
m, f, wcfgCancel := setupROFolder(t) m, f, wcfgCancel := setupROFolder(t)
defer wcfgCancel() defer wcfgCancel()
ffs := f.Filesystem() ffs := f.Filesystem(nil)
defer cleanupModel(m) defer cleanupModel(m)
addFakeConn(m, device1, f.ID) addFakeConn(m, device1, f.ID)
@@ -270,7 +270,7 @@ func TestRecvOnlyDeletedRemoteDrop(t *testing.T) {
m, f, wcfgCancel := setupROFolder(t) m, f, wcfgCancel := setupROFolder(t)
defer wcfgCancel() defer wcfgCancel()
ffs := f.Filesystem() ffs := f.Filesystem(nil)
defer cleanupModel(m) defer cleanupModel(m)
addFakeConn(m, device1, f.ID) addFakeConn(m, device1, f.ID)
@@ -335,7 +335,7 @@ func TestRecvOnlyRemoteUndoChanges(t *testing.T) {
m, f, wcfgCancel := setupROFolder(t) m, f, wcfgCancel := setupROFolder(t)
defer wcfgCancel() defer wcfgCancel()
ffs := f.Filesystem() ffs := f.Filesystem(nil)
defer cleanupModel(m) defer cleanupModel(m)
addFakeConn(m, device1, f.ID) addFakeConn(m, device1, f.ID)
@@ -425,7 +425,7 @@ func TestRecvOnlyRevertOwnID(t *testing.T) {
m, f, wcfgCancel := setupROFolder(t) m, f, wcfgCancel := setupROFolder(t)
defer wcfgCancel() defer wcfgCancel()
ffs := f.Filesystem() ffs := f.Filesystem(nil)
defer cleanupModel(m) defer cleanupModel(m)
addFakeConn(m, device1, f.ID) addFakeConn(m, device1, f.ID)
+1 -1
View File
@@ -1264,7 +1264,7 @@ func (f *sendReceiveFolder) copierRoutine(in <-chan copyBlocksState, pullChan ch
// Hope that it's usually in the same folder, so start with that one. // Hope that it's usually in the same folder, so start with that one.
folders := []string{f.folderID} folders := []string{f.folderID}
for folder, cfg := range f.model.cfg.Folders() { for folder, cfg := range f.model.cfg.Folders() {
folderFilesystems[folder] = cfg.Filesystem() folderFilesystems[folder] = cfg.Filesystem(nil)
if folder != f.folderID { if folder != f.folderID {
folders = append(folders, folder) folders = append(folders, folder)
} }
+14 -14
View File
@@ -109,7 +109,7 @@ func setupSendReceiveFolder(t testing.TB, files ...protocol.FileInfo) (*testMode
func cleanupSRFolder(f *sendReceiveFolder, m *testModel, wrapperCancel context.CancelFunc) { func cleanupSRFolder(f *sendReceiveFolder, m *testModel, wrapperCancel context.CancelFunc) {
wrapperCancel() wrapperCancel()
os.Remove(m.cfg.ConfigPath()) os.Remove(m.cfg.ConfigPath())
os.RemoveAll(f.Filesystem().URI()) os.RemoveAll(f.Filesystem(nil).URI())
} }
// Layout of the files: (indexes from the above array) // Layout of the files: (indexes from the above array)
@@ -172,7 +172,7 @@ func TestHandleFileWithTemp(t *testing.T) {
m, f, wcfgCancel := setupSendReceiveFolder(t, existingFile) m, f, wcfgCancel := setupSendReceiveFolder(t, existingFile)
defer cleanupSRFolder(f, m, wcfgCancel) defer cleanupSRFolder(f, m, wcfgCancel)
if _, err := prepareTmpFile(f.Filesystem()); err != nil { if _, err := prepareTmpFile(f.Filesystem(nil)); err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -230,7 +230,7 @@ func TestCopierFinder(t *testing.T) {
defer cleanupSRFolder(f, m, wcfgCancel) defer cleanupSRFolder(f, m, wcfgCancel)
if _, err := prepareTmpFile(f.Filesystem()); err != nil { if _, err := prepareTmpFile(f.Filesystem(nil)); err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -290,7 +290,7 @@ func TestCopierFinder(t *testing.T) {
} }
// Verify that the fetched blocks have actually been written to the temp file // Verify that the fetched blocks have actually been written to the temp file
blks, err := scanner.HashFile(context.TODO(), f.Filesystem(), tempFile, protocol.MinBlockSize, nil, false) blks, err := scanner.HashFile(context.TODO(), f.Filesystem(nil), tempFile, protocol.MinBlockSize, nil, false)
if err != nil { if err != nil {
t.Log(err) t.Log(err)
} }
@@ -308,7 +308,7 @@ func TestWeakHash(t *testing.T) {
// Setup the model/pull environment // Setup the model/pull environment
model, fo, wcfgCancel := setupSendReceiveFolder(t) model, fo, wcfgCancel := setupSendReceiveFolder(t)
defer cleanupSRFolder(fo, model, wcfgCancel) defer cleanupSRFolder(fo, model, wcfgCancel)
ffs := fo.Filesystem() ffs := fo.Filesystem(nil)
tempFile := fs.TempName("weakhash") tempFile := fs.TempName("weakhash")
var shift int64 = 10 var shift int64 = 10
@@ -673,7 +673,7 @@ func TestDeregisterOnFailInPull(t *testing.T) {
func TestIssue3164(t *testing.T) { func TestIssue3164(t *testing.T) {
m, f, wcfgCancel := setupSendReceiveFolder(t) m, f, wcfgCancel := setupSendReceiveFolder(t)
defer cleanupSRFolder(f, m, wcfgCancel) defer cleanupSRFolder(f, m, wcfgCancel)
ffs := f.Filesystem() ffs := f.Filesystem(nil)
tmpDir := ffs.URI() tmpDir := ffs.URI()
ignDir := filepath.Join("issue3164", "oktodelete") ignDir := filepath.Join("issue3164", "oktodelete")
@@ -764,7 +764,7 @@ func TestDiffEmpty(t *testing.T) {
func TestDeleteIgnorePerms(t *testing.T) { func TestDeleteIgnorePerms(t *testing.T) {
m, f, wcfgCancel := setupSendReceiveFolder(t) m, f, wcfgCancel := setupSendReceiveFolder(t)
defer cleanupSRFolder(f, m, wcfgCancel) defer cleanupSRFolder(f, m, wcfgCancel)
ffs := f.Filesystem() ffs := f.Filesystem(nil)
f.IgnorePerms = true f.IgnorePerms = true
name := "deleteIgnorePerms" name := "deleteIgnorePerms"
@@ -806,7 +806,7 @@ func TestCopyOwner(t *testing.T) {
f.folder.FolderConfiguration.CopyOwnershipFromParent = true f.folder.FolderConfiguration.CopyOwnershipFromParent = true
f.fset = newFileSet(t, f.ID, m.db) f.fset = newFileSet(t, f.ID, m.db)
f.mtimefs = f.fset.MtimeFS(f.Filesystem()) f.mtimefs = f.Filesystem(f.fset)
// Create a parent dir with a certain owner/group. // Create a parent dir with a certain owner/group.
@@ -905,7 +905,7 @@ func TestCopyOwner(t *testing.T) {
func TestSRConflictReplaceFileByDir(t *testing.T) { func TestSRConflictReplaceFileByDir(t *testing.T) {
m, f, wcfgCancel := setupSendReceiveFolder(t) m, f, wcfgCancel := setupSendReceiveFolder(t)
defer cleanupSRFolder(f, m, wcfgCancel) defer cleanupSRFolder(f, m, wcfgCancel)
ffs := f.Filesystem() ffs := f.Filesystem(nil)
name := "foo" name := "foo"
@@ -937,7 +937,7 @@ func TestSRConflictReplaceFileByDir(t *testing.T) {
func TestSRConflictReplaceFileByLink(t *testing.T) { func TestSRConflictReplaceFileByLink(t *testing.T) {
m, f, wcfgCancel := setupSendReceiveFolder(t) m, f, wcfgCancel := setupSendReceiveFolder(t)
defer cleanupSRFolder(f, m, wcfgCancel) defer cleanupSRFolder(f, m, wcfgCancel)
ffs := f.Filesystem() ffs := f.Filesystem(nil)
name := "foo" name := "foo"
@@ -970,7 +970,7 @@ func TestSRConflictReplaceFileByLink(t *testing.T) {
func TestDeleteBehindSymlink(t *testing.T) { func TestDeleteBehindSymlink(t *testing.T) {
m, f, wcfgCancel := setupSendReceiveFolder(t) m, f, wcfgCancel := setupSendReceiveFolder(t)
defer cleanupSRFolder(f, m, wcfgCancel) defer cleanupSRFolder(f, m, wcfgCancel)
ffs := f.Filesystem() ffs := f.Filesystem(nil)
destDir := createTmpDir() destDir := createTmpDir()
defer os.RemoveAll(destDir) defer os.RemoveAll(destDir)
@@ -1063,7 +1063,7 @@ func TestPullCtxCancel(t *testing.T) {
func TestPullDeleteUnscannedDir(t *testing.T) { func TestPullDeleteUnscannedDir(t *testing.T) {
m, f, wcfgCancel := setupSendReceiveFolder(t) m, f, wcfgCancel := setupSendReceiveFolder(t)
defer cleanupSRFolder(f, m, wcfgCancel) defer cleanupSRFolder(f, m, wcfgCancel)
ffs := f.Filesystem() ffs := f.Filesystem(nil)
dir := "foobar" dir := "foobar"
must(t, ffs.MkdirAll(dir, 0777)) must(t, ffs.MkdirAll(dir, 0777))
@@ -1092,7 +1092,7 @@ func TestPullDeleteUnscannedDir(t *testing.T) {
func TestPullCaseOnlyPerformFinish(t *testing.T) { func TestPullCaseOnlyPerformFinish(t *testing.T) {
m, f, wcfgCancel := setupSendReceiveFolder(t) m, f, wcfgCancel := setupSendReceiveFolder(t)
defer cleanupSRFolder(f, m, wcfgCancel) defer cleanupSRFolder(f, m, wcfgCancel)
ffs := f.Filesystem() ffs := f.Filesystem(nil)
name := "foo" name := "foo"
contents := []byte("contents") contents := []byte("contents")
@@ -1153,7 +1153,7 @@ func TestPullCaseOnlySymlink(t *testing.T) {
func testPullCaseOnlyDirOrSymlink(t *testing.T, dir bool) { func testPullCaseOnlyDirOrSymlink(t *testing.T, dir bool) {
m, f, wcfgCancel := setupSendReceiveFolder(t) m, f, wcfgCancel := setupSendReceiveFolder(t)
defer cleanupSRFolder(f, m, wcfgCancel) defer cleanupSRFolder(f, m, wcfgCancel)
ffs := f.Filesystem() ffs := f.Filesystem(nil)
name := "foo" name := "foo"
if dir { if dir {
+10 -10
View File
@@ -332,7 +332,7 @@ func (m *model) StartDeadlockDetector(timeout time.Duration) {
// Need to hold lock on m.fmut when calling this. // Need to hold lock on m.fmut when calling this.
func (m *model) addAndStartFolderLocked(cfg config.FolderConfiguration, fset *db.FileSet, cacheIgnoredFiles bool) { func (m *model) addAndStartFolderLocked(cfg config.FolderConfiguration, fset *db.FileSet, cacheIgnoredFiles bool) {
ignores := ignore.New(cfg.Filesystem(), ignore.WithCache(cacheIgnoredFiles)) ignores := ignore.New(cfg.Filesystem(nil), ignore.WithCache(cacheIgnoredFiles))
if cfg.Type != config.FolderTypeReceiveEncrypted { if cfg.Type != config.FolderTypeReceiveEncrypted {
if err := ignores.Load(".stignore"); err != nil && !fs.IsNotExist(err) { if err := ignores.Load(".stignore"); err != nil && !fs.IsNotExist(err) {
l.Warnln("Loading ignores:", err) l.Warnln("Loading ignores:", err)
@@ -396,7 +396,7 @@ func (m *model) addAndStartFolderLockedWithIgnores(cfg config.FolderConfiguratio
} }
// These are our metadata files, and they should always be hidden. // These are our metadata files, and they should always be hidden.
ffs := cfg.Filesystem() ffs := cfg.Filesystem(nil)
_ = ffs.Hide(config.DefaultMarkerName) _ = ffs.Hide(config.DefaultMarkerName)
_ = ffs.Hide(".stversions") _ = ffs.Hide(".stversions")
_ = ffs.Hide(".stignore") _ = ffs.Hide(".stignore")
@@ -428,7 +428,7 @@ func (m *model) warnAboutOverwritingProtectedFiles(cfg config.FolderConfiguratio
} }
// This is a bit of a hack. // This is a bit of a hack.
ffs := cfg.Filesystem() ffs := cfg.Filesystem(nil)
if ffs.Type() != fs.FilesystemTypeBasic { if ffs.Type() != fs.FilesystemTypeBasic {
return return
} }
@@ -478,7 +478,7 @@ func (m *model) removeFolder(cfg config.FolderConfiguration) {
if isPathUnique { if isPathUnique {
// Remove (if empty and removable) or move away (if non-empty or // Remove (if empty and removable) or move away (if non-empty or
// otherwise not removable) Syncthing-specific marker files. // otherwise not removable) Syncthing-specific marker files.
fs := cfg.Filesystem() fs := cfg.Filesystem(nil)
if err := fs.Remove(config.DefaultMarkerName); err != nil { if err := fs.Remove(config.DefaultMarkerName); err != nil {
moved := config.DefaultMarkerName + time.Now().Format(".removed-20060102-150405") moved := config.DefaultMarkerName + time.Now().Format(".removed-20060102-150405")
_ = fs.Rename(config.DefaultMarkerName, moved) _ = fs.Rename(config.DefaultMarkerName, moved)
@@ -1839,7 +1839,7 @@ func (m *model) Request(deviceID protocol.DeviceID, folder, name string, blockNo
// Grab the FS after limiting, as it causes I/O and we want to minimize // Grab the FS after limiting, as it causes I/O and we want to minimize
// the race time between the symlink check and the read. // the race time between the symlink check and the read.
folderFs := folderCfg.Filesystem() folderFs := folderCfg.Filesystem(nil)
if err := osutil.TraversesSymlink(folderFs, filepath.Dir(name)); err != nil { if err := osutil.TraversesSymlink(folderFs, filepath.Dir(name)); err != nil {
l.Debugf("%v REQ(in) traversal check: %s - %s: %q / %q o=%d s=%d", m, err, deviceID, folder, name, offset, size) l.Debugf("%v REQ(in) traversal check: %s - %s: %q / %q o=%d s=%d", m, err, deviceID, folder, name, offset, size)
@@ -2005,7 +2005,7 @@ func (m *model) GetMtimeMapping(folder string, file string) (fs.MtimeMapping, er
if !ok { if !ok {
return fs.MtimeMapping{}, ErrFolderMissing return fs.MtimeMapping{}, ErrFolderMissing
} }
return fs.GetMtimeMapping(ffs.MtimeFS(fcfg.Filesystem()), file) return fs.GetMtimeMapping(fcfg.Filesystem(ffs), file)
} }
// Connection returns the current connection for device, and a boolean whether a connection was found. // Connection returns the current connection for device, and a boolean whether a connection was found.
@@ -2039,7 +2039,7 @@ func (m *model) LoadIgnores(folder string) ([]string, []string, error) {
} }
if !ignoresOk { if !ignoresOk {
ignores = ignore.New(cfg.Filesystem()) ignores = ignore.New(cfg.Filesystem(nil))
} }
err := ignores.Load(".stignore") err := ignores.Load(".stignore")
@@ -2094,7 +2094,7 @@ func (m *model) setIgnores(cfg config.FolderConfiguration, content []string) err
return err return err
} }
if err := ignore.WriteIgnores(cfg.Filesystem(), ".stignore", content); err != nil { if err := ignore.WriteIgnores(cfg.Filesystem(nil), ".stignore", content); err != nil {
l.Warnln("Saving .stignore:", err) l.Warnln("Saving .stignore:", err)
return err return err
} }
@@ -3207,7 +3207,7 @@ type storedEncryptionToken struct {
} }
func readEncryptionToken(cfg config.FolderConfiguration) ([]byte, error) { func readEncryptionToken(cfg config.FolderConfiguration) ([]byte, error) {
fd, err := cfg.Filesystem().Open(encryptionTokenPath(cfg)) fd, err := cfg.Filesystem(nil).Open(encryptionTokenPath(cfg))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -3221,7 +3221,7 @@ func readEncryptionToken(cfg config.FolderConfiguration) ([]byte, error) {
func writeEncryptionToken(token []byte, cfg config.FolderConfiguration) error { func writeEncryptionToken(token []byte, cfg config.FolderConfiguration) error {
tokenName := encryptionTokenPath(cfg) tokenName := encryptionTokenPath(cfg)
fd, err := cfg.Filesystem().OpenFile(tokenName, fs.OptReadWrite|fs.OptCreate, 0666) fd, err := cfg.Filesystem(nil).OpenFile(tokenName, fs.OptReadWrite|fs.OptCreate, 0666)
if err != nil { if err != nil {
return err return err
} }
+28 -28
View File
@@ -222,7 +222,7 @@ func BenchmarkIndex_100(b *testing.B) {
func benchmarkIndex(b *testing.B, nfiles int) { func benchmarkIndex(b *testing.B, nfiles int) {
m, _, fcfg, wcfgCancel := setupModelWithConnection(b) m, _, fcfg, wcfgCancel := setupModelWithConnection(b)
defer wcfgCancel() defer wcfgCancel()
defer cleanupModelAndRemoveDir(m, fcfg.Filesystem().URI()) defer cleanupModelAndRemoveDir(m, fcfg.Filesystem(nil).URI())
files := genFiles(nfiles) files := genFiles(nfiles)
must(b, m.Index(device1, fcfg.ID, files)) must(b, m.Index(device1, fcfg.ID, files))
@@ -249,7 +249,7 @@ func BenchmarkIndexUpdate_10000_1(b *testing.B) {
func benchmarkIndexUpdate(b *testing.B, nfiles, nufiles int) { func benchmarkIndexUpdate(b *testing.B, nfiles, nufiles int) {
m, _, fcfg, wcfgCancel := setupModelWithConnection(b) m, _, fcfg, wcfgCancel := setupModelWithConnection(b)
defer wcfgCancel() defer wcfgCancel()
defer cleanupModelAndRemoveDir(m, fcfg.Filesystem().URI()) defer cleanupModelAndRemoveDir(m, fcfg.Filesystem(nil).URI())
files := genFiles(nfiles) files := genFiles(nfiles)
ufiles := genFiles(nufiles) ufiles := genFiles(nufiles)
@@ -1517,7 +1517,7 @@ func TestIgnores(t *testing.T) {
// Invalid path, treated like no patterns at all. // Invalid path, treated like no patterns at all.
fcfg := config.FolderConfiguration{ID: "fresh", Path: "XXX"} fcfg := config.FolderConfiguration{ID: "fresh", Path: "XXX"}
ignores := ignore.New(fcfg.Filesystem(), ignore.WithCache(m.cfg.Options().CacheIgnoredFiles)) ignores := ignore.New(fcfg.Filesystem(nil), ignore.WithCache(m.cfg.Options().CacheIgnoredFiles))
m.fmut.Lock() m.fmut.Lock()
m.folderCfgs[fcfg.ID] = fcfg m.folderCfgs[fcfg.ID] = fcfg
m.folderIgnores[fcfg.ID] = ignores m.folderIgnores[fcfg.ID] = ignores
@@ -1709,7 +1709,7 @@ func TestRWScanRecovery(t *testing.T) {
func TestGlobalDirectoryTree(t *testing.T) { func TestGlobalDirectoryTree(t *testing.T) {
m, _, fcfg, wCancel := setupModelWithConnection(t) m, _, fcfg, wCancel := setupModelWithConnection(t)
defer wCancel() defer wCancel()
defer cleanupModelAndRemoveDir(m, fcfg.Filesystem().URI()) defer cleanupModelAndRemoveDir(m, fcfg.Filesystem(nil).URI())
b := func(isfile bool, path ...string) protocol.FileInfo { b := func(isfile bool, path ...string) protocol.FileInfo {
typ := protocol.FileInfoTypeDirectory typ := protocol.FileInfoTypeDirectory
@@ -2012,7 +2012,7 @@ func BenchmarkTree_100_10(b *testing.B) {
func benchmarkTree(b *testing.B, n1, n2 int) { func benchmarkTree(b *testing.B, n1, n2 int) {
m, _, fcfg, wcfgCancel := setupModelWithConnection(b) m, _, fcfg, wcfgCancel := setupModelWithConnection(b)
defer wcfgCancel() defer wcfgCancel()
defer cleanupModelAndRemoveDir(m, fcfg.Filesystem().URI()) defer cleanupModelAndRemoveDir(m, fcfg.Filesystem(nil).URI())
m.ScanFolder(fcfg.ID) m.ScanFolder(fcfg.ID)
files := genDeepFiles(n1, n2) files := genDeepFiles(n1, n2)
@@ -2477,7 +2477,7 @@ func TestIssue2571(t *testing.T) {
w, fcfg, wCancel := tmpDefaultWrapper() w, fcfg, wCancel := tmpDefaultWrapper()
defer wCancel() defer wCancel()
testFs := fcfg.Filesystem() testFs := fcfg.Filesystem(nil)
defer os.RemoveAll(testFs.URI()) defer os.RemoveAll(testFs.URI())
for _, dir := range []string{"toLink", "linkTarget"} { for _, dir := range []string{"toLink", "linkTarget"} {
@@ -2516,7 +2516,7 @@ func TestIssue4573(t *testing.T) {
w, fcfg, wCancel := tmpDefaultWrapper() w, fcfg, wCancel := tmpDefaultWrapper()
defer wCancel() defer wCancel()
testFs := fcfg.Filesystem() testFs := fcfg.Filesystem(nil)
defer os.RemoveAll(testFs.URI()) defer os.RemoveAll(testFs.URI())
must(t, testFs.MkdirAll("inaccessible", 0755)) must(t, testFs.MkdirAll("inaccessible", 0755))
@@ -2546,7 +2546,7 @@ func TestIssue4573(t *testing.T) {
func TestInternalScan(t *testing.T) { func TestInternalScan(t *testing.T) {
w, fcfg, wCancel := tmpDefaultWrapper() w, fcfg, wCancel := tmpDefaultWrapper()
defer wCancel() defer wCancel()
testFs := fcfg.Filesystem() testFs := fcfg.Filesystem(nil)
defer os.RemoveAll(testFs.URI()) defer os.RemoveAll(testFs.URI())
testCases := map[string]func(protocol.FileInfo) bool{ testCases := map[string]func(protocol.FileInfo) bool{
@@ -2644,7 +2644,7 @@ func TestCustomMarkerName(t *testing.T) {
func TestRemoveDirWithContent(t *testing.T) { func TestRemoveDirWithContent(t *testing.T) {
m, _, fcfg, wcfgCancel := setupModelWithConnection(t) m, _, fcfg, wcfgCancel := setupModelWithConnection(t)
defer wcfgCancel() defer wcfgCancel()
tfs := fcfg.Filesystem() tfs := fcfg.Filesystem(nil)
defer cleanupModelAndRemoveDir(m, tfs.URI()) defer cleanupModelAndRemoveDir(m, tfs.URI())
tfs.MkdirAll("dirwith", 0755) tfs.MkdirAll("dirwith", 0755)
@@ -2706,7 +2706,7 @@ func TestIssue4475(t *testing.T) {
m, conn, fcfg, wcfgCancel := setupModelWithConnection(t) m, conn, fcfg, wcfgCancel := setupModelWithConnection(t)
defer wcfgCancel() defer wcfgCancel()
defer cleanupModel(m) defer cleanupModel(m)
testFs := fcfg.Filesystem() testFs := fcfg.Filesystem(nil)
// Scenario: Dir is deleted locally and before syncing/index exchange // Scenario: Dir is deleted locally and before syncing/index exchange
// happens, a file is create in that dir on the remote. // happens, a file is create in that dir on the remote.
@@ -2769,7 +2769,7 @@ func TestVersionRestore(t *testing.T) {
fcfg := newFolderConfiguration(defaultCfgWrapper, "default", "default", fs.FilesystemTypeBasic, dir) fcfg := newFolderConfiguration(defaultCfgWrapper, "default", "default", fs.FilesystemTypeBasic, dir)
fcfg.Versioning.Type = "simple" fcfg.Versioning.Type = "simple"
fcfg.FSWatcherEnabled = false fcfg.FSWatcherEnabled = false
filesystem := fcfg.Filesystem() filesystem := fcfg.Filesystem(nil)
rawConfig := config.Configuration{ rawConfig := config.Configuration{
Folders: []config.FolderConfiguration{fcfg}, Folders: []config.FolderConfiguration{fcfg},
@@ -3005,7 +3005,7 @@ func TestIssue4094(t *testing.T) {
t.Fatalf("failed setting ignores: %v", err) t.Fatalf("failed setting ignores: %v", err)
} }
if _, err := fcfg.Filesystem().Lstat(".stignore"); err != nil { if _, err := fcfg.Filesystem(nil).Lstat(".stignore"); err != nil {
t.Fatalf("failed stating .stignore: %v", err) t.Fatalf("failed stating .stignore: %v", err)
} }
} }
@@ -3037,7 +3037,7 @@ func TestIssue4903(t *testing.T) {
t.Fatalf("expected path missing error, got: %v", err) t.Fatalf("expected path missing error, got: %v", err)
} }
if _, err := fcfg.Filesystem().Lstat("."); !fs.IsNotExist(err) { if _, err := fcfg.Filesystem(nil).Lstat("."); !fs.IsNotExist(err) {
t.Fatalf("Expected missing path error, got: %v", err) t.Fatalf("Expected missing path error, got: %v", err)
} }
} }
@@ -3067,7 +3067,7 @@ func TestParentOfUnignored(t *testing.T) {
m, cancel := newState(t, defaultCfg) m, cancel := newState(t, defaultCfg)
defer cleanupModel(m) defer cleanupModel(m)
defer cancel() defer cancel()
defer defaultFolderConfig.Filesystem().Remove(".stignore") defer defaultFolderConfig.Filesystem(nil).Remove(".stignore")
m.SetIgnores("default", []string{"!quux", "*"}) m.SetIgnores("default", []string{"!quux", "*"})
@@ -3184,7 +3184,7 @@ func TestConnCloseOnRestart(t *testing.T) {
w, fcfg, wCancel := tmpDefaultWrapper() w, fcfg, wCancel := tmpDefaultWrapper()
defer wCancel() defer wCancel()
m := setupModel(t, w) m := setupModel(t, w)
defer cleanupModelAndRemoveDir(m, fcfg.Filesystem().URI()) defer cleanupModelAndRemoveDir(m, fcfg.Filesystem(nil).URI())
br := &testutils.BlockingRW{} br := &testutils.BlockingRW{}
nw := &testutils.NoopRW{} nw := &testutils.NoopRW{}
@@ -3220,7 +3220,7 @@ func TestConnCloseOnRestart(t *testing.T) {
func TestModTimeWindow(t *testing.T) { func TestModTimeWindow(t *testing.T) {
w, fcfg, wCancel := tmpDefaultWrapper() w, fcfg, wCancel := tmpDefaultWrapper()
defer wCancel() defer wCancel()
tfs := fcfg.Filesystem() tfs := fcfg.Filesystem(nil)
fcfg.RawModTimeWindowS = 2 fcfg.RawModTimeWindowS = 2
setFolder(t, w, fcfg) setFolder(t, w, fcfg)
m := setupModel(t, w) m := setupModel(t, w)
@@ -3277,7 +3277,7 @@ func TestModTimeWindow(t *testing.T) {
func TestDevicePause(t *testing.T) { func TestDevicePause(t *testing.T) {
m, _, fcfg, wcfgCancel := setupModelWithConnection(t) m, _, fcfg, wcfgCancel := setupModelWithConnection(t)
defer wcfgCancel() defer wcfgCancel()
defer cleanupModelAndRemoveDir(m, fcfg.Filesystem().URI()) defer cleanupModelAndRemoveDir(m, fcfg.Filesystem(nil).URI())
sub := m.evLogger.Subscribe(events.DevicePaused) sub := m.evLogger.Subscribe(events.DevicePaused)
defer sub.Unsubscribe() defer sub.Unsubscribe()
@@ -3304,7 +3304,7 @@ func TestDevicePause(t *testing.T) {
func TestDeviceWasSeen(t *testing.T) { func TestDeviceWasSeen(t *testing.T) {
m, _, fcfg, wcfgCancel := setupModelWithConnection(t) m, _, fcfg, wcfgCancel := setupModelWithConnection(t)
defer wcfgCancel() defer wcfgCancel()
defer cleanupModelAndRemoveDir(m, fcfg.Filesystem().URI()) defer cleanupModelAndRemoveDir(m, fcfg.Filesystem(nil).URI())
m.deviceWasSeen(device1) m.deviceWasSeen(device1)
@@ -3399,7 +3399,7 @@ func TestRenameSequenceOrder(t *testing.T) {
numFiles := 20 numFiles := 20
ffs := fcfg.Filesystem() ffs := fcfg.Filesystem(nil)
for i := 0; i < numFiles; i++ { for i := 0; i < numFiles; i++ {
v := fmt.Sprintf("%d", i) v := fmt.Sprintf("%d", i)
writeFile(t, ffs, v, []byte(v)) writeFile(t, ffs, v, []byte(v))
@@ -3468,7 +3468,7 @@ func TestRenameSameFile(t *testing.T) {
m := setupModel(t, wcfg) m := setupModel(t, wcfg)
defer cleanupModel(m) defer cleanupModel(m)
ffs := fcfg.Filesystem() ffs := fcfg.Filesystem(nil)
writeFile(t, ffs, "file", []byte("file")) writeFile(t, ffs, "file", []byte("file"))
m.ScanFolders() m.ScanFolders()
@@ -3519,7 +3519,7 @@ func TestRenameEmptyFile(t *testing.T) {
m := setupModel(t, wcfg) m := setupModel(t, wcfg)
defer cleanupModel(m) defer cleanupModel(m)
ffs := fcfg.Filesystem() ffs := fcfg.Filesystem(nil)
writeFile(t, ffs, "file", []byte("data")) writeFile(t, ffs, "file", []byte("data"))
writeFile(t, ffs, "empty", nil) writeFile(t, ffs, "empty", nil)
@@ -3596,7 +3596,7 @@ func TestBlockListMap(t *testing.T) {
m := setupModel(t, wcfg) m := setupModel(t, wcfg)
defer cleanupModel(m) defer cleanupModel(m)
ffs := fcfg.Filesystem() ffs := fcfg.Filesystem(nil)
writeFile(t, ffs, "one", []byte("content")) writeFile(t, ffs, "one", []byte("content"))
writeFile(t, ffs, "two", []byte("content")) writeFile(t, ffs, "two", []byte("content"))
writeFile(t, ffs, "three", []byte("content")) writeFile(t, ffs, "three", []byte("content"))
@@ -3664,7 +3664,7 @@ func TestScanRenameCaseOnly(t *testing.T) {
m := setupModel(t, wcfg) m := setupModel(t, wcfg)
defer cleanupModel(m) defer cleanupModel(m)
ffs := fcfg.Filesystem() ffs := fcfg.Filesystem(nil)
name := "foo" name := "foo"
writeFile(t, ffs, name, []byte("contents")) writeFile(t, ffs, name, []byte("contents"))
@@ -3782,7 +3782,7 @@ func TestAddFolderCompletion(t *testing.T) {
func TestScanDeletedROChangedOnSR(t *testing.T) { func TestScanDeletedROChangedOnSR(t *testing.T) {
m, _, fcfg, wCancel := setupModelWithConnection(t) m, _, fcfg, wCancel := setupModelWithConnection(t)
ffs := fcfg.Filesystem() ffs := fcfg.Filesystem(nil)
defer wCancel() defer wCancel()
defer cleanupModelAndRemoveDir(m, ffs.URI()) defer cleanupModelAndRemoveDir(m, ffs.URI())
fcfg.Type = config.FolderTypeReceiveOnly fcfg.Type = config.FolderTypeReceiveOnly
@@ -3886,7 +3886,7 @@ func testConfigChangeTriggersClusterConfigs(t *testing.T, expectFirst, expectSec
func TestIssue6961(t *testing.T) { func TestIssue6961(t *testing.T) {
wcfg, fcfg, wcfgCancel := tmpDefaultWrapper() wcfg, fcfg, wcfgCancel := tmpDefaultWrapper()
defer wcfgCancel() defer wcfgCancel()
tfs := fcfg.Filesystem() tfs := fcfg.Filesystem(nil)
waiter, err := wcfg.Modify(func(cfg *config.Configuration) { waiter, err := wcfg.Modify(func(cfg *config.Configuration) {
cfg.SetDevice(newDeviceConfiguration(cfg.Defaults.Device, device2, "device2")) cfg.SetDevice(newDeviceConfiguration(cfg.Defaults.Device, device2, "device2"))
fcfg.Type = config.FolderTypeReceiveOnly fcfg.Type = config.FolderTypeReceiveOnly
@@ -3956,7 +3956,7 @@ func TestIssue6961(t *testing.T) {
func TestCompletionEmptyGlobal(t *testing.T) { func TestCompletionEmptyGlobal(t *testing.T) {
m, _, fcfg, wcfgCancel := setupModelWithConnection(t) m, _, fcfg, wcfgCancel := setupModelWithConnection(t)
defer wcfgCancel() defer wcfgCancel()
defer cleanupModelAndRemoveDir(m, fcfg.Filesystem().URI()) defer cleanupModelAndRemoveDir(m, fcfg.Filesystem(nil).URI())
files := []protocol.FileInfo{{Name: "foo", Version: protocol.Vector{}.Update(myID.Short()), Sequence: 1}} files := []protocol.FileInfo{{Name: "foo", Version: protocol.Vector{}.Update(myID.Short()), Sequence: 1}}
m.fmut.Lock() m.fmut.Lock()
m.folderFiles[fcfg.ID].Update(protocol.LocalDeviceID, files) m.folderFiles[fcfg.ID].Update(protocol.LocalDeviceID, files)
@@ -4157,7 +4157,7 @@ func TestCCFolderNotRunning(t *testing.T) {
// Create the folder, but don't start it. // Create the folder, but don't start it.
w, fcfg, wCancel := tmpDefaultWrapper() w, fcfg, wCancel := tmpDefaultWrapper()
defer wCancel() defer wCancel()
tfs := fcfg.Filesystem() tfs := fcfg.Filesystem(nil)
m := newModel(t, w, myID, "syncthing", "dev", nil) m := newModel(t, w, myID, "syncthing", "dev", nil)
defer cleanupModelAndRemoveDir(m, tfs.URI()) defer cleanupModelAndRemoveDir(m, tfs.URI())
@@ -4264,7 +4264,7 @@ func TestDeletedNotLocallyChangedReceiveEncrypted(t *testing.T) {
func deletedNotLocallyChanged(t *testing.T, ft config.FolderType) { func deletedNotLocallyChanged(t *testing.T, ft config.FolderType) {
w, fcfg, wCancel := tmpDefaultWrapper() w, fcfg, wCancel := tmpDefaultWrapper()
tfs := fcfg.Filesystem() tfs := fcfg.Filesystem(nil)
fcfg.Type = ft fcfg.Type = ft
setFolder(t, w, fcfg) setFolder(t, w, fcfg)
defer wCancel() defer wCancel()
+20 -20
View File
@@ -32,7 +32,7 @@ func TestRequestSimple(t *testing.T) {
m, fc, fcfg, wcfgCancel := setupModelWithConnection(t) m, fc, fcfg, wcfgCancel := setupModelWithConnection(t)
defer wcfgCancel() defer wcfgCancel()
tfs := fcfg.Filesystem() tfs := fcfg.Filesystem(nil)
defer cleanupModelAndRemoveDir(m, tfs.URI()) defer cleanupModelAndRemoveDir(m, tfs.URI())
// We listen for incoming index updates and trigger when we see one for // We listen for incoming index updates and trigger when we see one for
@@ -79,7 +79,7 @@ func TestSymlinkTraversalRead(t *testing.T) {
m, fc, fcfg, wcfgCancel := setupModelWithConnection(t) m, fc, fcfg, wcfgCancel := setupModelWithConnection(t)
defer wcfgCancel() defer wcfgCancel()
defer cleanupModelAndRemoveDir(m, fcfg.Filesystem().URI()) defer cleanupModelAndRemoveDir(m, fcfg.Filesystem(nil).URI())
// We listen for incoming index updates and trigger when we see one for // We listen for incoming index updates and trigger when we see one for
// the expected test file. // the expected test file.
@@ -122,7 +122,7 @@ func TestSymlinkTraversalWrite(t *testing.T) {
m, fc, fcfg, wcfgCancel := setupModelWithConnection(t) m, fc, fcfg, wcfgCancel := setupModelWithConnection(t)
defer wcfgCancel() defer wcfgCancel()
defer cleanupModelAndRemoveDir(m, fcfg.Filesystem().URI()) defer cleanupModelAndRemoveDir(m, fcfg.Filesystem(nil).URI())
// We listen for incoming index updates and trigger when we see one for // We listen for incoming index updates and trigger when we see one for
// the expected names. // the expected names.
@@ -181,7 +181,7 @@ func TestRequestCreateTmpSymlink(t *testing.T) {
m, fc, fcfg, wcfgCancel := setupModelWithConnection(t) m, fc, fcfg, wcfgCancel := setupModelWithConnection(t)
defer wcfgCancel() defer wcfgCancel()
defer cleanupModelAndRemoveDir(m, fcfg.Filesystem().URI()) defer cleanupModelAndRemoveDir(m, fcfg.Filesystem(nil).URI())
// We listen for incoming index updates and trigger when we see one for // We listen for incoming index updates and trigger when we see one for
// the expected test file. // the expected test file.
@@ -224,7 +224,7 @@ func TestRequestVersioningSymlinkAttack(t *testing.T) {
w, fcfg, wCancel := tmpDefaultWrapper() w, fcfg, wCancel := tmpDefaultWrapper()
defer wCancel() defer wCancel()
defer func() { defer func() {
os.RemoveAll(fcfg.Filesystem().URI()) os.RemoveAll(fcfg.Filesystem(nil).URI())
os.Remove(w.ConfigPath()) os.Remove(w.ConfigPath())
}() }()
@@ -301,7 +301,7 @@ func pullInvalidIgnored(t *testing.T, ft config.FolderType) {
w, wCancel := createTmpWrapper(defaultCfgWrapper.RawCopy()) w, wCancel := createTmpWrapper(defaultCfgWrapper.RawCopy())
defer wCancel() defer wCancel()
fcfg := testFolderConfigTmp() fcfg := testFolderConfigTmp()
fss := fcfg.Filesystem() fss := fcfg.Filesystem(nil)
fcfg.Type = ft fcfg.Type = ft
setFolder(t, w, fcfg) setFolder(t, w, fcfg)
m := setupModel(t, w) m := setupModel(t, w)
@@ -430,7 +430,7 @@ func pullInvalidIgnored(t *testing.T, ft config.FolderType) {
func TestIssue4841(t *testing.T) { func TestIssue4841(t *testing.T) {
m, fc, fcfg, wcfgCancel := setupModelWithConnection(t) m, fc, fcfg, wcfgCancel := setupModelWithConnection(t)
defer wcfgCancel() defer wcfgCancel()
defer cleanupModelAndRemoveDir(m, fcfg.Filesystem().URI()) defer cleanupModelAndRemoveDir(m, fcfg.Filesystem(nil).URI())
received := make(chan []protocol.FileInfo) received := make(chan []protocol.FileInfo)
fc.setIndexFn(func(_ context.Context, _ string, fs []protocol.FileInfo) error { fc.setIndexFn(func(_ context.Context, _ string, fs []protocol.FileInfo) error {
@@ -478,7 +478,7 @@ func TestIssue4841(t *testing.T) {
func TestRescanIfHaveInvalidContent(t *testing.T) { func TestRescanIfHaveInvalidContent(t *testing.T) {
m, fc, fcfg, wcfgCancel := setupModelWithConnection(t) m, fc, fcfg, wcfgCancel := setupModelWithConnection(t)
defer wcfgCancel() defer wcfgCancel()
tfs := fcfg.Filesystem() tfs := fcfg.Filesystem(nil)
defer cleanupModelAndRemoveDir(m, tfs.URI()) defer cleanupModelAndRemoveDir(m, tfs.URI())
payload := []byte("hello") payload := []byte("hello")
@@ -544,7 +544,7 @@ func TestRescanIfHaveInvalidContent(t *testing.T) {
func TestParentDeletion(t *testing.T) { func TestParentDeletion(t *testing.T) {
m, fc, fcfg, wcfgCancel := setupModelWithConnection(t) m, fc, fcfg, wcfgCancel := setupModelWithConnection(t)
defer wcfgCancel() defer wcfgCancel()
testFs := fcfg.Filesystem() testFs := fcfg.Filesystem(nil)
defer cleanupModelAndRemoveDir(m, testFs.URI()) defer cleanupModelAndRemoveDir(m, testFs.URI())
parent := "foo" parent := "foo"
@@ -623,7 +623,7 @@ func TestRequestSymlinkWindows(t *testing.T) {
m, fc, fcfg, wcfgCancel := setupModelWithConnection(t) m, fc, fcfg, wcfgCancel := setupModelWithConnection(t)
defer wcfgCancel() defer wcfgCancel()
defer cleanupModelAndRemoveDir(m, fcfg.Filesystem().URI()) defer cleanupModelAndRemoveDir(m, fcfg.Filesystem(nil).URI())
received := make(chan []protocol.FileInfo) received := make(chan []protocol.FileInfo)
fc.setIndexFn(func(_ context.Context, folder string, fs []protocol.FileInfo) error { fc.setIndexFn(func(_ context.Context, folder string, fs []protocol.FileInfo) error {
@@ -691,7 +691,7 @@ func equalContents(path string, contents []byte) error {
func TestRequestRemoteRenameChanged(t *testing.T) { func TestRequestRemoteRenameChanged(t *testing.T) {
m, fc, fcfg, wcfgCancel := setupModelWithConnection(t) m, fc, fcfg, wcfgCancel := setupModelWithConnection(t)
defer wcfgCancel() defer wcfgCancel()
tfs := fcfg.Filesystem() tfs := fcfg.Filesystem(nil)
tmpDir := tfs.URI() tmpDir := tfs.URI()
defer cleanupModelAndRemoveDir(m, tfs.URI()) defer cleanupModelAndRemoveDir(m, tfs.URI())
@@ -825,7 +825,7 @@ func TestRequestRemoteRenameChanged(t *testing.T) {
func TestRequestRemoteRenameConflict(t *testing.T) { func TestRequestRemoteRenameConflict(t *testing.T) {
m, fc, fcfg, wcfgCancel := setupModelWithConnection(t) m, fc, fcfg, wcfgCancel := setupModelWithConnection(t)
defer wcfgCancel() defer wcfgCancel()
tfs := fcfg.Filesystem() tfs := fcfg.Filesystem(nil)
tmpDir := tfs.URI() tmpDir := tfs.URI()
defer cleanupModelAndRemoveDir(m, tmpDir) defer cleanupModelAndRemoveDir(m, tmpDir)
@@ -916,7 +916,7 @@ func TestRequestRemoteRenameConflict(t *testing.T) {
func TestRequestDeleteChanged(t *testing.T) { func TestRequestDeleteChanged(t *testing.T) {
m, fc, fcfg, wcfgCancel := setupModelWithConnection(t) m, fc, fcfg, wcfgCancel := setupModelWithConnection(t)
defer wcfgCancel() defer wcfgCancel()
tfs := fcfg.Filesystem() tfs := fcfg.Filesystem(nil)
defer cleanupModelAndRemoveDir(m, tfs.URI()) defer cleanupModelAndRemoveDir(m, tfs.URI())
done := make(chan struct{}) done := make(chan struct{})
@@ -984,7 +984,7 @@ func TestRequestDeleteChanged(t *testing.T) {
func TestNeedFolderFiles(t *testing.T) { func TestNeedFolderFiles(t *testing.T) {
m, fc, fcfg, wcfgCancel := setupModelWithConnection(t) m, fc, fcfg, wcfgCancel := setupModelWithConnection(t)
defer wcfgCancel() defer wcfgCancel()
tfs := fcfg.Filesystem() tfs := fcfg.Filesystem(nil)
tmpDir := tfs.URI() tmpDir := tfs.URI()
defer cleanupModelAndRemoveDir(m, tmpDir) defer cleanupModelAndRemoveDir(m, tmpDir)
@@ -1032,7 +1032,7 @@ func TestIgnoreDeleteUnignore(t *testing.T) {
w, fcfg, wCancel := tmpDefaultWrapper() w, fcfg, wCancel := tmpDefaultWrapper()
defer wCancel() defer wCancel()
m := setupModel(t, w) m := setupModel(t, w)
fss := fcfg.Filesystem() fss := fcfg.Filesystem(nil)
tmpDir := fss.URI() tmpDir := fss.URI()
defer cleanupModelAndRemoveDir(m, tmpDir) defer cleanupModelAndRemoveDir(m, tmpDir)
@@ -1127,7 +1127,7 @@ func TestIgnoreDeleteUnignore(t *testing.T) {
func TestRequestLastFileProgress(t *testing.T) { func TestRequestLastFileProgress(t *testing.T) {
m, fc, fcfg, wcfgCancel := setupModelWithConnection(t) m, fc, fcfg, wcfgCancel := setupModelWithConnection(t)
defer wcfgCancel() defer wcfgCancel()
tfs := fcfg.Filesystem() tfs := fcfg.Filesystem(nil)
defer cleanupModelAndRemoveDir(m, tfs.URI()) defer cleanupModelAndRemoveDir(m, tfs.URI())
done := make(chan struct{}) done := make(chan struct{})
@@ -1162,7 +1162,7 @@ func TestRequestIndexSenderPause(t *testing.T) {
m, fc, fcfg, wcfgCancel := setupModelWithConnection(t) m, fc, fcfg, wcfgCancel := setupModelWithConnection(t)
defer wcfgCancel() defer wcfgCancel()
tfs := fcfg.Filesystem() tfs := fcfg.Filesystem(nil)
defer cleanupModelAndRemoveDir(m, tfs.URI()) defer cleanupModelAndRemoveDir(m, tfs.URI())
indexChan := make(chan []protocol.FileInfo) indexChan := make(chan []protocol.FileInfo)
@@ -1275,7 +1275,7 @@ func TestRequestIndexSenderPause(t *testing.T) {
func TestRequestIndexSenderClusterConfigBeforeStart(t *testing.T) { func TestRequestIndexSenderClusterConfigBeforeStart(t *testing.T) {
w, fcfg, wCancel := tmpDefaultWrapper() w, fcfg, wCancel := tmpDefaultWrapper()
defer wCancel() defer wCancel()
tfs := fcfg.Filesystem() tfs := fcfg.Filesystem(nil)
dir1 := "foo" dir1 := "foo"
dir2 := "bar" dir2 := "bar"
@@ -1342,7 +1342,7 @@ func TestRequestReceiveEncrypted(t *testing.T) {
w, fcfg, wCancel := tmpDefaultWrapper() w, fcfg, wCancel := tmpDefaultWrapper()
defer wCancel() defer wCancel()
tfs := fcfg.Filesystem() tfs := fcfg.Filesystem(nil)
fcfg.Type = config.FolderTypeReceiveEncrypted fcfg.Type = config.FolderTypeReceiveEncrypted
setFolder(t, w, fcfg) setFolder(t, w, fcfg)
@@ -1450,7 +1450,7 @@ func TestRequestGlobalInvalidToValid(t *testing.T) {
must(t, err) must(t, err)
waiter.Wait() waiter.Wait()
addFakeConn(m, device2, fcfg.ID) addFakeConn(m, device2, fcfg.ID)
tfs := fcfg.Filesystem() tfs := fcfg.Filesystem(nil)
defer cleanupModelAndRemoveDir(m, tfs.URI()) defer cleanupModelAndRemoveDir(m, tfs.URI())
indexChan := make(chan []protocol.FileInfo, 1) indexChan := make(chan []protocol.FileInfo, 1)
+2 -2
View File
@@ -40,7 +40,7 @@ func init() {
defaultCfgWrapper, defaultCfgWrapperCancel = createTmpWrapper(config.New(myID)) defaultCfgWrapper, defaultCfgWrapperCancel = createTmpWrapper(config.New(myID))
defaultFolderConfig = testFolderConfig("testdata") defaultFolderConfig = testFolderConfig("testdata")
defaultFs = defaultFolderConfig.Filesystem() defaultFs = defaultFolderConfig.Filesystem(nil)
waiter, _ := defaultCfgWrapper.Modify(func(cfg *config.Configuration) { waiter, _ := defaultCfgWrapper.Modify(func(cfg *config.Configuration) {
cfg.SetDevice(newDeviceConfiguration(cfg.Defaults.Device, device1, "device1")) cfg.SetDevice(newDeviceConfiguration(cfg.Defaults.Device, device1, "device1"))
@@ -308,7 +308,7 @@ func folderIgnoresAlwaysReload(t testing.TB, m *testModel, fcfg config.FolderCon
t.Helper() t.Helper()
m.removeFolder(fcfg) m.removeFolder(fcfg)
fset := newFileSet(t, fcfg.ID, m.db) fset := newFileSet(t, fcfg.ID, m.db)
ignores := ignore.New(fcfg.Filesystem(), ignore.WithCache(true), ignore.WithChangeDetector(newAlwaysChanged())) ignores := ignore.New(fcfg.Filesystem(nil), ignore.WithCache(true), ignore.WithChangeDetector(newAlwaysChanged()))
m.fmut.Lock() m.fmut.Lock()
m.addAndStartFolderLockedWithIgnores(fcfg, fset, ignores) m.addAndStartFolderLockedWithIgnores(fcfg, fset, ignores)
m.fmut.Unlock() m.fmut.Unlock()
+9 -5
View File
@@ -38,10 +38,14 @@ type testfile struct {
type testfileList []testfile type testfileList []testfile
const (
testFsType = fs.FilesystemTypeBasic
testFsLocation = "testdata"
)
var ( var (
testFs fs.Filesystem testFs fs.Filesystem
testFsType = fs.FilesystemTypeBasic testdata = testfileList{
testdata = testfileList{
{"afile", 4, "b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c"}, {"afile", 4, "b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c"},
{"dir1", 128, ""}, {"dir1", 128, ""},
{filepath.Join("dir1", "dfile"), 5, "49ae93732fcf8d63fe1cce759664982dbd5b23161f007dba8561862adc96d063"}, {filepath.Join("dir1", "dfile"), 5, "49ae93732fcf8d63fe1cce759664982dbd5b23161f007dba8561862adc96d063"},
@@ -58,7 +62,7 @@ func init() {
// potentially taking down the box... // potentially taking down the box...
rdebug.SetMaxStack(10 * 1 << 20) rdebug.SetMaxStack(10 * 1 << 20)
testFs = fs.NewFilesystem(fs.FilesystemTypeBasic, "testdata") testFs = fs.NewFilesystem(testFsType, testFsLocation)
} }
func TestWalkSub(t *testing.T) { func TestWalkSub(t *testing.T) {
@@ -258,7 +262,7 @@ func TestNormalizationDarwinCaseFS(t *testing.T) {
return return
} }
testFs := fs.NewCaseFilesystem(testFs) testFs := fs.NewFilesystem(testFsType, testFsLocation, new(fs.OptionDetectCaseConflicts))
testFs.RemoveAll("normalization") testFs.RemoveAll("normalization")
defer testFs.RemoveAll("normalization") defer testFs.RemoveAll("normalization")
+1 -1
View File
@@ -41,7 +41,7 @@ func newExternal(cfg config.FolderConfiguration) Versioner {
s := external{ s := external{
command: command, command: command,
filesystem: cfg.Filesystem(), filesystem: cfg.Filesystem(nil),
} }
l.Debugf("instantiated %#v", s) l.Debugf("instantiated %#v", s)
+1 -1
View File
@@ -40,7 +40,7 @@ func newSimple(cfg config.FolderConfiguration) Versioner {
s := simple{ s := simple{
keep: keep, keep: keep,
cleanoutDays: cleanoutDays, cleanoutDays: cleanoutDays,
folderFs: cfg.Filesystem(), folderFs: cfg.Filesystem(nil),
versionsFs: versionerFsFromFolderCfg(cfg), versionsFs: versionerFsFromFolderCfg(cfg),
copyRangeMethod: cfg.CopyRangeMethod, copyRangeMethod: cfg.CopyRangeMethod,
} }
+1 -1
View File
@@ -70,7 +70,7 @@ func TestSimpleVersioningVersionCount(t *testing.T) {
}, },
}, },
} }
fs := cfg.Filesystem() fs := cfg.Filesystem(nil)
v := newSimple(cfg) v := newSimple(cfg)
+1 -1
View File
@@ -44,7 +44,7 @@ func newStaggered(cfg config.FolderConfiguration) Versioner {
versionsFs := versionerFsFromFolderCfg(cfg) versionsFs := versionerFsFromFolderCfg(cfg)
s := &staggered{ s := &staggered{
folderFs: cfg.Filesystem(), folderFs: cfg.Filesystem(nil),
versionsFs: versionsFs, versionsFs: versionsFs,
interval: [4]interval{ interval: [4]interval{
{30, 60 * 60}, // first hour -> 30 sec between versions {30, 60 * 60}, // first hour -> 30 sec between versions
+1 -1
View File
@@ -33,7 +33,7 @@ func newTrashcan(cfg config.FolderConfiguration) Versioner {
// On error we default to 0, "do not clean out the trash can" // On error we default to 0, "do not clean out the trash can"
s := &trashcan{ s := &trashcan{
folderFs: cfg.Filesystem(), folderFs: cfg.Filesystem(nil),
versionsFs: versionerFsFromFolderCfg(cfg), versionsFs: versionerFsFromFolderCfg(cfg),
cleanoutDays: cleanoutDays, cleanoutDays: cleanoutDays,
copyRangeMethod: cfg.CopyRangeMethod, copyRangeMethod: cfg.CopyRangeMethod,
+1 -1
View File
@@ -38,7 +38,7 @@ func TestTrashcanArchiveRestoreSwitcharoo(t *testing.T) {
FSPath: tmpDir2, FSPath: tmpDir2,
}, },
} }
folderFs := cfg.Filesystem() folderFs := cfg.Filesystem(nil)
versionsFs := fs.NewFilesystem(fs.FilesystemTypeBasic, tmpDir2) versionsFs := fs.NewFilesystem(fs.FilesystemTypeBasic, tmpDir2)
+1 -1
View File
@@ -256,7 +256,7 @@ func restoreFile(method fs.CopyRangeMethod, src, dst fs.Filesystem, filePath str
} }
func versionerFsFromFolderCfg(cfg config.FolderConfiguration) (versionsFs fs.Filesystem) { func versionerFsFromFolderCfg(cfg config.FolderConfiguration) (versionsFs fs.Filesystem) {
folderFs := cfg.Filesystem() folderFs := cfg.Filesystem(nil)
if cfg.Versioning.FSPath == "" { if cfg.Versioning.FSPath == "" {
versionsFs = fs.NewFilesystem(folderFs.Type(), filepath.Join(folderFs.URI(), ".stversions")) versionsFs = fs.NewFilesystem(folderFs.Type(), filepath.Join(folderFs.URI(), ".stversions"))
} else if cfg.Versioning.FSType == fs.FilesystemTypeBasic && !filepath.IsAbs(cfg.Versioning.FSPath) { } else if cfg.Versioning.FSType == fs.FilesystemTypeBasic && !filepath.IsAbs(cfg.Versioning.FSPath) {