lib/model: Run more tests in tmp dir (#5527)

This commit is contained in:
Simon Frei 2019-02-12 16:04:04 +01:00 committed by Jakob Borg
parent 4299af1c63
commit 5fd2cab102
4 changed files with 187 additions and 177 deletions

View File

@ -75,27 +75,24 @@ func setUpFile(filename string, blockNumbers []int) protocol.FileInfo {
} }
} }
func setUpModel(files ...protocol.FileInfo) *Model { func setupSendReceiveFolder(files ...protocol.FileInfo) (*Model, *sendReceiveFolder, string) {
db := db.OpenMemory() w := createTmpWrapper(defaultCfg)
model := NewModel(defaultCfgWrapper, myID, "syncthing", "dev", db, nil) model := NewModel(w, myID, "syncthing", "dev", db.OpenMemory(), nil)
model.AddFolder(defaultFolderConfig) fcfg, tmpDir := testFolderConfigTmp()
model.AddFolder(fcfg)
// Update index // Update index
if files != nil {
model.updateLocalsFromScanning("default", files) model.updateLocalsFromScanning("default", files)
return model
} }
func setUpSendReceiveFolder(model *Model) *sendReceiveFolder {
f := &sendReceiveFolder{ f := &sendReceiveFolder{
folder: folder{ folder: folder{
stateTracker: newStateTracker("default"), stateTracker: newStateTracker("default"),
model: model, model: model,
initialScanFinished: make(chan struct{}), initialScanFinished: make(chan struct{}),
ctx: context.TODO(), ctx: context.TODO(),
FolderConfiguration: config.FolderConfiguration{ FolderConfiguration: fcfg,
FilesystemType: fs.FilesystemTypeBasic,
Path: "testdata",
PullerMaxPendingKiB: defaultPullerPendingKiB,
},
}, },
queue: newJobQueue(), queue: newJobQueue(),
@ -107,7 +104,7 @@ func setUpSendReceiveFolder(model *Model) *sendReceiveFolder {
// Folders are never actually started, so no initial scan will be done // Folders are never actually started, so no initial scan will be done
close(f.initialScanFinished) close(f.initialScanFinished)
return f return model, f, tmpDir
} }
// Layout of the files: (indexes from the above array) // Layout of the files: (indexes from the above array)
@ -125,8 +122,12 @@ func TestHandleFile(t *testing.T) {
requiredFile := existingFile requiredFile := existingFile
requiredFile.Blocks = blocks[1:] requiredFile.Blocks = blocks[1:]
m := setUpModel(existingFile) m, f, tmpDir := setupSendReceiveFolder(existingFile)
f := setUpSendReceiveFolder(m) defer func() {
os.Remove(m.cfg.ConfigPath())
os.Remove(tmpDir)
}()
copyChan := make(chan copyBlocksState, 1) copyChan := make(chan copyBlocksState, 1)
dbUpdateChan := make(chan dbUpdateJob, 1) dbUpdateChan := make(chan dbUpdateJob, 1)
@ -167,8 +168,16 @@ func TestHandleFileWithTemp(t *testing.T) {
requiredFile := existingFile requiredFile := existingFile
requiredFile.Blocks = blocks[1:] requiredFile.Blocks = blocks[1:]
m := setUpModel(existingFile) m, f, tmpDir := setupSendReceiveFolder(existingFile)
f := setUpSendReceiveFolder(m) defer func() {
os.Remove(m.cfg.ConfigPath())
os.Remove(tmpDir)
}()
if _, err := prepareTmpFile(f.Filesystem()); err != nil {
t.Fatal(err)
}
copyChan := make(chan copyBlocksState, 1) copyChan := make(chan copyBlocksState, 1)
dbUpdateChan := make(chan dbUpdateJob, 1) dbUpdateChan := make(chan dbUpdateJob, 1)
@ -197,8 +206,6 @@ func TestHandleFileWithTemp(t *testing.T) {
} }
func TestCopierFinder(t *testing.T) { func TestCopierFinder(t *testing.T) {
testOs := &fatalOs{t}
// After diff between required and existing we should: // After diff between required and existing we should:
// Copy: 1, 2, 3, 4, 6, 7, 8 // Copy: 1, 2, 3, 4, 6, 7, 8
// Since there is no existing file, nor a temp file // Since there is no existing file, nor a temp file
@ -206,9 +213,7 @@ func TestCopierFinder(t *testing.T) {
// After dropping out blocks found locally: // After dropping out blocks found locally:
// Pull: 1, 5, 6, 8 // Pull: 1, 5, 6, 8
tempFile := filepath.Join("testdata", fs.TempName("file2")) tempFile := fs.TempName("file2")
testOs.Remove(tempFile)
defer testOs.Remove(tempFile)
existingBlocks := []int{0, 2, 3, 4, 0, 0, 7, 0} existingBlocks := []int{0, 2, 3, 4, 0, 0, 7, 0}
existingFile := setUpFile(fs.TempName("file"), existingBlocks) existingFile := setUpFile(fs.TempName("file"), existingBlocks)
@ -216,8 +221,16 @@ func TestCopierFinder(t *testing.T) {
requiredFile.Blocks = blocks[1:] requiredFile.Blocks = blocks[1:]
requiredFile.Name = "file2" requiredFile.Name = "file2"
m := setUpModel(existingFile) m, f, tmpDir := setupSendReceiveFolder(existingFile)
f := setUpSendReceiveFolder(m) defer func() {
os.Remove(m.cfg.ConfigPath())
os.Remove(tmpDir)
}()
if _, err := prepareTmpFile(f.Filesystem()); err != nil {
t.Fatal(err)
}
copyChan := make(chan copyBlocksState) copyChan := make(chan copyBlocksState)
pullChan := make(chan pullBlockState, 4) pullChan := make(chan pullBlockState, 4)
finisherChan := make(chan *sharedPullerState, 1) finisherChan := make(chan *sharedPullerState, 1)
@ -259,7 +272,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(), fs.NewFilesystem(fs.FilesystemTypeBasic, "."), tempFile, protocol.MinBlockSize, nil, false) blks, err := scanner.HashFile(context.TODO(), f.Filesystem(), tempFile, protocol.MinBlockSize, nil, false)
if err != nil { if err != nil {
t.Log(err) t.Log(err)
} }
@ -273,9 +286,15 @@ func TestCopierFinder(t *testing.T) {
} }
func TestWeakHash(t *testing.T) { func TestWeakHash(t *testing.T) {
testOs := &fatalOs{t} // Setup the model/pull environment
model, fo, tmpDir := setupSendReceiveFolder()
defer func() {
os.Remove(model.cfg.ConfigPath())
os.Remove(tmpDir)
}()
ffs := fo.Filesystem()
tempFile := filepath.Join("testdata", fs.TempName("weakhash")) tempFile := fs.TempName("weakhash")
var shift int64 = 10 var shift int64 = 10
var size int64 = 1 << 20 var size int64 = 1 << 20
expectBlocks := int(size / protocol.MinBlockSize) expectBlocks := int(size / protocol.MinBlockSize)
@ -284,18 +303,12 @@ func TestWeakHash(t *testing.T) {
expectPulls++ expectPulls++
} }
cleanup := func() { f, err := ffs.Create("weakhash")
for _, path := range []string{tempFile, "testdata/weakhash"} { if err != nil {
testOs.Remove(path) t.Fatal(err)
} }
}
cleanup()
defer cleanup()
f := testOs.Create("testdata/weakhash")
defer f.Close() defer f.Close()
_, err := io.CopyN(f, rand.Reader, size) _, err = io.CopyN(f, rand.Reader, size)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
@ -337,9 +350,8 @@ func TestWeakHash(t *testing.T) {
ModifiedS: info.ModTime().Unix() + 1, ModifiedS: info.ModTime().Unix() + 1,
} }
// Setup the model/pull environment model.updateLocalsFromScanning("default", []protocol.FileInfo{existingFile})
m := setUpModel(existingFile)
fo := setUpSendReceiveFolder(m)
copyChan := make(chan copyBlocksState) copyChan := make(chan copyBlocksState)
pullChan := make(chan pullBlockState, expectBlocks) pullChan := make(chan pullBlockState, expectBlocks)
finisherChan := make(chan *sharedPullerState, 1) finisherChan := make(chan *sharedPullerState, 1)
@ -372,7 +384,9 @@ func TestWeakHash(t *testing.T) {
} }
finish.fd.Close() finish.fd.Close()
testOs.Remove(tempFile) if err := ffs.Remove(tempFile); err != nil {
t.Fatal(err)
}
// Test 2 - using weak hash, expectPulls blocks pulled. // Test 2 - using weak hash, expectPulls blocks pulled.
fo.WeakHashThresholdPct = -1 fo.WeakHashThresholdPct = -1
@ -405,7 +419,11 @@ func TestCopierCleanup(t *testing.T) {
// Create a file // Create a file
file := setUpFile("test", []int{0}) file := setUpFile("test", []int{0})
m := setUpModel(file) m, _, tmpDir := setupSendReceiveFolder(file)
defer func() {
os.Remove(m.cfg.ConfigPath())
os.Remove(tmpDir)
}()
file.Blocks = []protocol.BlockInfo{blocks[1]} file.Blocks = []protocol.BlockInfo{blocks[1]}
file.Version = file.Version.Update(myID.Short()) file.Version = file.Version.Update(myID.Short())
@ -435,21 +453,17 @@ func TestCopierCleanup(t *testing.T) {
} }
func TestDeregisterOnFailInCopy(t *testing.T) { func TestDeregisterOnFailInCopy(t *testing.T) {
testOs := &fatalOs{t}
file := setUpFile("filex", []int{0, 2, 0, 0, 5, 0, 0, 8}) file := setUpFile("filex", []int{0, 2, 0, 0, 5, 0, 0, 8})
defer testOs.Remove("testdata/" + fs.TempName("filex"))
db := db.OpenMemory() m, f, tmpDir := setupSendReceiveFolder()
defer func() {
m := NewModel(defaultCfgWrapper, myID, "syncthing", "dev", db, nil) os.Remove(m.cfg.ConfigPath())
m.AddFolder(defaultFolderConfig) os.Remove(tmpDir)
}()
// Set up our evet subscription early // Set up our evet subscription early
s := events.Default.Subscribe(events.ItemFinished) s := events.Default.Subscribe(events.ItemFinished)
f := setUpSendReceiveFolder(m)
// queue.Done should be called by the finisher routine // queue.Done should be called by the finisher routine
f.queue.Push("filex", 0, time.Time{}) f.queue.Push("filex", 0, time.Time{})
f.queue.Pop() f.queue.Pop()
@ -529,20 +543,17 @@ func TestDeregisterOnFailInCopy(t *testing.T) {
} }
func TestDeregisterOnFailInPull(t *testing.T) { func TestDeregisterOnFailInPull(t *testing.T) {
testOs := &fatalOs{t}
file := setUpFile("filex", []int{0, 2, 0, 0, 5, 0, 0, 8}) file := setUpFile("filex", []int{0, 2, 0, 0, 5, 0, 0, 8})
defer testOs.Remove("testdata/" + fs.TempName("filex"))
db := db.OpenMemory() m, f, tmpDir := setupSendReceiveFolder()
m := NewModel(defaultCfgWrapper, myID, "syncthing", "dev", db, nil) defer func() {
m.AddFolder(defaultFolderConfig) os.Remove(m.cfg.ConfigPath())
os.Remove(tmpDir)
}()
// Set up our evet subscription early // Set up our evet subscription early
s := events.Default.Subscribe(events.ItemFinished) s := events.Default.Subscribe(events.ItemFinished)
f := setUpSendReceiveFolder(m)
// queue.Done should be called by the finisher routine // queue.Done should be called by the finisher routine
f.queue.Push("filex", 0, time.Time{}) f.queue.Push("filex", 0, time.Time{})
f.queue.Pop() f.queue.Pop()
@ -612,26 +623,30 @@ func TestDeregisterOnFailInPull(t *testing.T) {
} }
func TestIssue3164(t *testing.T) { func TestIssue3164(t *testing.T) {
m := setUpModel(protocol.FileInfo{}) m, f, tmpDir := setupSendReceiveFolder()
f := setUpSendReceiveFolder(m) defer func() {
os.Remove(m.cfg.ConfigPath())
os.Remove(tmpDir)
}()
defaultFs.RemoveAll("issue3164") ffs := f.Filesystem()
defer defaultFs.RemoveAll("issue3164")
if err := defaultFs.MkdirAll("issue3164/oktodelete/foobar", 0777); err != nil { ignDir := filepath.Join("issue3164", "oktodelete")
subDir := filepath.Join(ignDir, "foobar")
if err := ffs.MkdirAll(subDir, 0777); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if err := ioutil.WriteFile("testdata/issue3164/oktodelete/foobar/file", []byte("Hello"), 0644); err != nil { if err := ioutil.WriteFile(filepath.Join(tmpDir, subDir, "file"), []byte("Hello"), 0644); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if err := ioutil.WriteFile("testdata/issue3164/oktodelete/file", []byte("Hello"), 0644); err != nil { if err := ioutil.WriteFile(filepath.Join(tmpDir, ignDir, "file"), []byte("Hello"), 0644); err != nil {
t.Fatal(err) t.Fatal(err)
} }
file := protocol.FileInfo{ file := protocol.FileInfo{
Name: "issue3164", Name: "issue3164",
} }
matcher := ignore.New(defaultFs) matcher := ignore.New(ffs)
if err := matcher.Parse(bytes.NewBufferString("(?d)oktodelete"), ""); err != nil { if err := matcher.Parse(bytes.NewBufferString("(?d)oktodelete"), ""); err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -640,7 +655,7 @@ func TestIssue3164(t *testing.T) {
f.handleDeleteDir(file, matcher, dbUpdateChan, make(chan string)) f.handleDeleteDir(file, matcher, dbUpdateChan, make(chan string))
if _, err := defaultFs.Stat("testdata/issue3164"); !fs.IsNotExist(err) { if _, err := ffs.Stat("issue3164"); !fs.IsNotExist(err) {
t.Fatal(err) t.Fatal(err)
} }
} }
@ -707,8 +722,11 @@ func TestDiffEmpty(t *testing.T) {
// option is true and the permissions do not match between the file on disk and // option is true and the permissions do not match between the file on disk and
// in the db. // in the db.
func TestDeleteIgnorePerms(t *testing.T) { func TestDeleteIgnorePerms(t *testing.T) {
m := setUpModel() m, f, tmpDir := setupSendReceiveFolder()
f := setUpSendReceiveFolder(m) defer func() {
os.Remove(m.cfg.ConfigPath())
os.Remove(tmpDir)
}()
f.IgnorePerms = true f.IgnorePerms = true
ffs := f.Filesystem() ffs := f.Filesystem()
@ -717,7 +735,6 @@ func TestDeleteIgnorePerms(t *testing.T) {
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
defer ffs.Remove(name)
defer file.Close() defer file.Close()
stat, err := file.Stat() stat, err := file.Stat()
@ -761,24 +778,10 @@ func TestCopyOwner(t *testing.T) {
// Set up a folder with the CopyParentOwner bit and backed by a fake // Set up a folder with the CopyParentOwner bit and backed by a fake
// filesystem. // filesystem.
m := setUpModel() m, f, _ := setupSendReceiveFolder()
f := &sendReceiveFolder{ defer os.Remove(m.cfg.ConfigPath())
folder: folder{ f.folder.FolderConfiguration = config.NewFolderConfiguration(m.id, f.ID, f.Label, fs.FilesystemTypeFake, "/TestCopyOwner")
stateTracker: newStateTracker("default"), f.folder.FolderConfiguration.CopyOwnershipFromParent = true
model: m,
initialScanFinished: make(chan struct{}),
ctx: context.TODO(),
FolderConfiguration: config.FolderConfiguration{
FilesystemType: fs.FilesystemTypeFake,
Path: "/TestCopyOwner",
CopyOwnershipFromParent: true,
},
},
queue: newJobQueue(),
pullErrors: make(map[string]string),
pullErrorsMut: sync.NewMutex(),
}
f.fs = f.Filesystem() f.fs = f.Filesystem()

View File

@ -11,6 +11,7 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"math/rand" "math/rand"
"net" "net"
@ -123,12 +124,8 @@ func TestMain(m *testing.M) {
} }
} }
tmpName := fs.TempName("file") tmpName, err := prepareTmpFile(defaultFs)
if err := osutil.Copy(defaultFs, "tmpfile", tmpName); err != nil { if err != nil {
panic(err)
}
future := time.Now().Add(time.Hour)
if err := os.Chtimes(filepath.Join("testdata", tmpName), future, future); err != nil {
panic(err) panic(err)
} }
@ -142,6 +139,28 @@ func TestMain(m *testing.M) {
os.Exit(exitCode) os.Exit(exitCode)
} }
func prepareTmpFile(to fs.Filesystem) (string, error) {
tmpName := fs.TempName("file")
in, err := defaultFs.Open("tmpfile")
if err != nil {
return "", err
}
defer in.Close()
out, err := to.Create(tmpName)
if err != nil {
return "", err
}
defer out.Close()
if _, err = io.Copy(out, in); err != nil {
return "", err
}
future := time.Now().Add(time.Hour)
if err := os.Chtimes(filepath.Join("testdata", tmpName), future, future); err != nil {
return "", err
}
return tmpName, nil
}
func createTmpWrapper(cfg config.Configuration) *config.Wrapper { func createTmpWrapper(cfg config.Configuration) *config.Wrapper {
tmpFile, err := ioutil.TempFile(tmpLocation, "syncthing-testConfig-") tmpFile, err := ioutil.TempFile(tmpLocation, "syncthing-testConfig-")
if err != nil { if err != nil {
@ -2879,15 +2898,13 @@ func TestIssue2571(t *testing.T) {
t.Skip("Scanning symlinks isn't supported on windows") t.Skip("Scanning symlinks isn't supported on windows")
} }
err := defaultFs.MkdirAll("replaceDir", 0755) w, tmpDir := tmpDefaultWrapper()
if err != nil {
t.Fatal(err)
}
defer func() { defer func() {
defaultFs.RemoveAll("replaceDir") os.RemoveAll(tmpDir)
os.Remove(w.ConfigPath())
}() }()
testFs := fs.NewFilesystem(fs.FilesystemTypeBasic, filepath.Join(defaultFs.URI(), "replaceDir")) testFs := fs.NewFilesystem(fs.FilesystemTypeBasic, tmpDir)
for _, dir := range []string{"toLink", "linkTarget"} { for _, dir := range []string{"toLink", "linkTarget"} {
err := testFs.MkdirAll(dir, 0775) err := testFs.MkdirAll(dir, 0775)
@ -2901,9 +2918,9 @@ func TestIssue2571(t *testing.T) {
fd.Close() fd.Close()
} }
m := setupModel(defaultCfgWrapper) m := setupModel(w)
if err = testFs.RemoveAll("toLink"); err != nil { if err := testFs.RemoveAll("toLink"); err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -2913,12 +2930,12 @@ func TestIssue2571(t *testing.T) {
m.ScanFolder("default") m.ScanFolder("default")
if dir, ok := m.CurrentFolderFile("default", filepath.Join("replaceDir", "toLink")); !ok { if dir, ok := m.CurrentFolderFile("default", "toLink"); !ok {
t.Fatalf("Dir missing in db") t.Fatalf("Dir missing in db")
} else if !dir.IsSymlink() { } else if !dir.IsSymlink() {
t.Errorf("Dir wasn't changed to symlink") t.Errorf("Dir wasn't changed to symlink")
} }
if file, ok := m.CurrentFolderFile("default", filepath.Join("replaceDir", "toLink", "a")); !ok { if file, ok := m.CurrentFolderFile("default", filepath.Join("toLink", "a")); !ok {
t.Fatalf("File missing in db") t.Fatalf("File missing in db")
} else if !file.Deleted { } else if !file.Deleted {
t.Errorf("File below symlink has not been marked as deleted") t.Errorf("File below symlink has not been marked as deleted")
@ -2931,25 +2948,30 @@ func TestIssue4573(t *testing.T) {
t.Skip("Can't make the dir inaccessible on windows") t.Skip("Can't make the dir inaccessible on windows")
} }
err := defaultFs.MkdirAll("inaccessible", 0755) w, tmpDir := tmpDefaultWrapper()
defer func() {
os.RemoveAll(tmpDir)
os.Remove(w.ConfigPath())
}()
testFs := fs.NewFilesystem(fs.FilesystemTypeBasic, tmpDir)
err := testFs.MkdirAll("inaccessible", 0755)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer func() { defer testFs.Chmod("inaccessible", 0777)
defaultFs.Chmod("inaccessible", 0777)
defaultFs.RemoveAll("inaccessible")
}()
file := filepath.Join("inaccessible", "a") file := filepath.Join("inaccessible", "a")
fd, err := defaultFs.Create(file) fd, err := testFs.Create(file)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
fd.Close() fd.Close()
m := setupModel(defaultCfgWrapper) m := setupModel(w)
err = defaultFs.Chmod("inaccessible", 0000) err = testFs.Chmod("inaccessible", 0000)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -2966,15 +2988,13 @@ func TestIssue4573(t *testing.T) {
// TestInternalScan checks whether various fs operations are correctly represented // TestInternalScan checks whether various fs operations are correctly represented
// in the db after scanning. // in the db after scanning.
func TestInternalScan(t *testing.T) { func TestInternalScan(t *testing.T) {
err := defaultFs.MkdirAll("internalScan", 0755) w, tmpDir := tmpDefaultWrapper()
if err != nil {
t.Fatal(err)
}
defer func() { defer func() {
defaultFs.RemoveAll("internalScan") os.RemoveAll(tmpDir)
os.Remove(w.ConfigPath())
}() }()
testFs := fs.NewFilesystem(fs.FilesystemTypeBasic, filepath.Join(defaultFs.URI(), "internalScan")) testFs := fs.NewFilesystem(fs.FilesystemTypeBasic, tmpDir)
testCases := map[string]func(protocol.FileInfo) bool{ testCases := map[string]func(protocol.FileInfo) bool{
"removeDir": func(f protocol.FileInfo) bool { "removeDir": func(f protocol.FileInfo) bool {
@ -3010,10 +3030,10 @@ func TestInternalScan(t *testing.T) {
} }
} }
m := setupModel(defaultCfgWrapper) m := setupModel(w)
for _, dir := range baseDirs { for _, dir := range baseDirs {
if err = testFs.RemoveAll(dir); err != nil { if err := testFs.RemoveAll(dir); err != nil {
t.Fatal(err) t.Fatal(err)
} }
} }
@ -3027,7 +3047,7 @@ func TestInternalScan(t *testing.T) {
m.ScanFolder("default") m.ScanFolder("default")
for path, cond := range testCases { for path, cond := range testCases {
if f, ok := m.CurrentFolderFile("default", filepath.Join("internalScan", path)); !ok { if f, ok := m.CurrentFolderFile("default", path); !ok {
t.Fatalf("%v missing in db", path) t.Fatalf("%v missing in db", path)
} else if cond(f) { } else if cond(f) {
t.Errorf("Incorrect db entry for %v", path) t.Errorf("Incorrect db entry for %v", path)
@ -3166,31 +3186,32 @@ func TestRemoveDirWithContent(t *testing.T) {
} }
func TestIssue4475(t *testing.T) { func TestIssue4475(t *testing.T) {
m, conn, tmpDir, w := setupModelWithConnection()
defer func() { defer func() {
defaultFs.RemoveAll("delDir") m.Stop()
os.RemoveAll(tmpDir)
os.Remove(w.ConfigPath())
}() }()
err := defaultFs.MkdirAll("delDir", 0755) testFs := fs.NewFilesystem(fs.FilesystemTypeBasic, tmpDir)
if err != nil {
t.Fatal(err)
}
m := setupModel(defaultCfgWrapper)
defer m.Stop()
// 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.
// This should result in the directory being recreated and added to the // This should result in the directory being recreated and added to the
// db locally. // db locally.
if err = defaultFs.RemoveAll("delDir"); err != nil { err := testFs.MkdirAll("delDir", 0755)
if err != nil {
t.Fatal(err) t.Fatal(err)
} }
m.ScanFolder("default") m.ScanFolder("default")
conn := addFakeConn(m, device1) if err = testFs.RemoveAll("delDir"); err != nil {
conn.folder = "default" t.Fatal(err)
}
m.ScanFolder("default")
if fcfg, ok := m.cfg.Folder("default"); !ok || !fcfg.SharedWith(device1) { if fcfg, ok := m.cfg.Folder("default"); !ok || !fcfg.SharedWith(device1) {
t.Fatal("not shared with device1") t.Fatal("not shared with device1")

View File

@ -18,7 +18,6 @@ import (
"time" "time"
"github.com/syncthing/syncthing/lib/config" "github.com/syncthing/syncthing/lib/config"
"github.com/syncthing/syncthing/lib/db"
"github.com/syncthing/syncthing/lib/events" "github.com/syncthing/syncthing/lib/events"
"github.com/syncthing/syncthing/lib/fs" "github.com/syncthing/syncthing/lib/fs"
"github.com/syncthing/syncthing/lib/ignore" "github.com/syncthing/syncthing/lib/ignore"
@ -231,8 +230,6 @@ func TestRequestCreateTmpSymlink(t *testing.T) {
} }
func TestRequestVersioningSymlinkAttack(t *testing.T) { func TestRequestVersioningSymlinkAttack(t *testing.T) {
testOs := &fatalOs{t}
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
t.Skip("no symlink support on Windows") t.Skip("no symlink support on Windows")
} }
@ -240,33 +237,19 @@ func TestRequestVersioningSymlinkAttack(t *testing.T) {
// Sets up a folder with trashcan versioning and tries to use a // Sets up a folder with trashcan versioning and tries to use a
// deleted symlink to escape // deleted symlink to escape
tmpDir := createTmpDir() w, tmpDir := tmpDefaultWrapper()
defer testOs.RemoveAll(tmpDir) defer func() {
os.RemoveAll(tmpDir)
os.Remove(w.ConfigPath())
}()
cfg := defaultCfgWrapper.RawCopy() fcfg := w.FolderList()[0]
cfg.Folders[0] = config.NewFolderConfiguration(myID, "default", "default", fs.FilesystemTypeBasic, tmpDir) fcfg.Versioning = config.VersioningConfiguration{Type: "trashcan"}
cfg.Folders[0].Devices = []config.FolderDeviceConfiguration{ w.SetFolder(fcfg)
{DeviceID: myID},
{DeviceID: device1},
}
cfg.Folders[0].Versioning = config.VersioningConfiguration{
Type: "trashcan",
}
w := createTmpWrapper(cfg)
defer testOs.Remove(w.ConfigPath())
db := db.OpenMemory() m, fc := setupModelWithConnectionFromWrapper(w)
m := NewModel(w, myID, "syncthing", "dev", db, nil)
m.AddFolder(cfg.Folders[0])
m.ServeBackground()
m.StartFolder("default")
defer m.Stop() defer m.Stop()
defer testOs.RemoveAll(tmpDir)
fc := addFakeConn(m, device1)
fc.folder = "default"
// Create a temporary directory that we will use as target to see if // Create a temporary directory that we will use as target to see if
// we can escape to it // we can escape to it
tmpdir, err := ioutil.TempDir("", "syncthing-test") tmpdir, err := ioutil.TempDir("", "syncthing-test")
@ -656,13 +639,11 @@ func TestRequestSymlinkWindows(t *testing.T) {
t.Skip("windows specific test") t.Skip("windows specific test")
} }
testOs := &fatalOs{t}
m, fc, tmpDir, w := setupModelWithConnection() m, fc, tmpDir, w := setupModelWithConnection()
defer func() { defer func() {
m.Stop() m.Stop()
testOs.RemoveAll(tmpDir) os.RemoveAll(tmpDir)
testOs.Remove(w.ConfigPath()) os.Remove(w.ConfigPath())
}() }()
done := make(chan struct{}) done := make(chan struct{})
@ -719,6 +700,13 @@ func TestRequestSymlinkWindows(t *testing.T) {
} }
} }
func tmpDefaultWrapper() (*config.Wrapper, string) {
w := createTmpWrapper(defaultCfgWrapper.RawCopy())
fcfg, tmpDir := testFolderConfigTmp()
w.SetFolder(fcfg)
return w, tmpDir
}
func testFolderConfigTmp() (config.FolderConfiguration, string) { func testFolderConfigTmp() (config.FolderConfiguration, string) {
tmpDir := createTmpDir() tmpDir := createTmpDir()
return testFolderConfig(tmpDir), tmpDir return testFolderConfig(tmpDir), tmpDir
@ -732,9 +720,7 @@ func testFolderConfig(path string) config.FolderConfiguration {
} }
func setupModelWithConnection() (*Model, *fakeConnection, string, *config.Wrapper) { func setupModelWithConnection() (*Model, *fakeConnection, string, *config.Wrapper) {
w := createTmpWrapper(defaultCfgWrapper.RawCopy()) w, tmpDir := tmpDefaultWrapper()
fcfg, tmpDir := testFolderConfigTmp()
w.SetFolder(fcfg)
m, fc := setupModelWithConnectionFromWrapper(w) m, fc := setupModelWithConnectionFromWrapper(w)
return m, fc, tmpDir, w return m, fc, tmpDir, w
} }

View File

@ -7,6 +7,7 @@
package model package model
import ( import (
"os"
"testing" "testing"
"github.com/syncthing/syncthing/lib/fs" "github.com/syncthing/syncthing/lib/fs"
@ -15,18 +16,17 @@ import (
// Test creating temporary file inside read-only directory // Test creating temporary file inside read-only directory
func TestReadOnlyDir(t *testing.T) { func TestReadOnlyDir(t *testing.T) {
testOs := &fatalOs{t}
// Create a read only directory, clean it up afterwards. // Create a read only directory, clean it up afterwards.
testOs.Mkdir("testdata/read_only_dir", 0555) tmpDir := createTmpDir()
defer func() { defer os.RemoveAll(tmpDir)
testOs.Chmod("testdata/read_only_dir", 0755) if err := os.Chmod(tmpDir, 0555); err != nil {
testOs.RemoveAll("testdata/read_only_dir") t.Fatal(err)
}() }
defer os.Chmod(tmpDir, 0755)
s := sharedPullerState{ s := sharedPullerState{
fs: fs.NewFilesystem(fs.FilesystemTypeBasic, "testdata"), fs: fs.NewFilesystem(fs.FilesystemTypeBasic, tmpDir),
tempName: "read_only_dir/.temp_name", tempName: ".temp_name",
mut: sync.NewRWMutex(), mut: sync.NewRWMutex(),
} }