Quellcode durchsuchen

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

Simon Frei vor 7 Jahren
Ursprung
Commit
5fd2cab102

+ 93 - 90
lib/model/folder_sendrecv_test.go

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

+ 65 - 44
lib/model/model_test.go

@@ -11,6 +11,7 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
+	"io"
 	"io/ioutil"
 	"math/rand"
 	"net"
@@ -123,12 +124,8 @@ func TestMain(m *testing.M) {
 		}
 	}
 
-	tmpName := fs.TempName("file")
-	if err := osutil.Copy(defaultFs, "tmpfile", tmpName); err != nil {
-		panic(err)
-	}
-	future := time.Now().Add(time.Hour)
-	if err := os.Chtimes(filepath.Join("testdata", tmpName), future, future); err != nil {
+	tmpName, err := prepareTmpFile(defaultFs)
+	if err != nil {
 		panic(err)
 	}
 
@@ -142,6 +139,28 @@ func TestMain(m *testing.M) {
 	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 {
 	tmpFile, err := ioutil.TempFile(tmpLocation, "syncthing-testConfig-")
 	if err != nil {
@@ -2879,15 +2898,13 @@ func TestIssue2571(t *testing.T) {
 		t.Skip("Scanning symlinks isn't supported on windows")
 	}
 
-	err := defaultFs.MkdirAll("replaceDir", 0755)
-	if err != nil {
-		t.Fatal(err)
-	}
+	w, tmpDir := tmpDefaultWrapper()
 	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"} {
 		err := testFs.MkdirAll(dir, 0775)
@@ -2901,9 +2918,9 @@ func TestIssue2571(t *testing.T) {
 		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)
 	}
 
@@ -2913,12 +2930,12 @@ func TestIssue2571(t *testing.T) {
 
 	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")
 	} else if !dir.IsSymlink() {
 		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")
 	} else if !file.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")
 	}
 
-	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 {
 		t.Fatal(err)
 	}
-	defer func() {
-		defaultFs.Chmod("inaccessible", 0777)
-		defaultFs.RemoveAll("inaccessible")
-	}()
+	defer testFs.Chmod("inaccessible", 0777)
 
 	file := filepath.Join("inaccessible", "a")
-	fd, err := defaultFs.Create(file)
+	fd, err := testFs.Create(file)
 	if err != nil {
 		t.Fatal(err)
 	}
 	fd.Close()
 
-	m := setupModel(defaultCfgWrapper)
+	m := setupModel(w)
 
-	err = defaultFs.Chmod("inaccessible", 0000)
+	err = testFs.Chmod("inaccessible", 0000)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -2966,15 +2988,13 @@ func TestIssue4573(t *testing.T) {
 // TestInternalScan checks whether various fs operations are correctly represented
 // in the db after scanning.
 func TestInternalScan(t *testing.T) {
-	err := defaultFs.MkdirAll("internalScan", 0755)
-	if err != nil {
-		t.Fatal(err)
-	}
+	w, tmpDir := tmpDefaultWrapper()
 	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{
 		"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 {
-		if err = testFs.RemoveAll(dir); err != nil {
+		if err := testFs.RemoveAll(dir); err != nil {
 			t.Fatal(err)
 		}
 	}
@@ -3027,7 +3047,7 @@ func TestInternalScan(t *testing.T) {
 	m.ScanFolder("default")
 
 	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)
 		} else if cond(f) {
 			t.Errorf("Incorrect db entry for %v", path)
@@ -3166,31 +3186,32 @@ func TestRemoveDirWithContent(t *testing.T) {
 }
 
 func TestIssue4475(t *testing.T) {
+	m, conn, tmpDir, w := setupModelWithConnection()
 	defer func() {
-		defaultFs.RemoveAll("delDir")
+		m.Stop()
+		os.RemoveAll(tmpDir)
+		os.Remove(w.ConfigPath())
 	}()
 
-	err := defaultFs.MkdirAll("delDir", 0755)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	m := setupModel(defaultCfgWrapper)
-	defer m.Stop()
+	testFs := fs.NewFilesystem(fs.FilesystemTypeBasic, tmpDir)
 
 	// Scenario: Dir is deleted locally and before syncing/index exchange
 	// happens, a file is create in that dir on the remote.
 	// This should result in the directory being recreated and added to the
 	// db locally.
 
-	if err = defaultFs.RemoveAll("delDir"); err != nil {
+	err := testFs.MkdirAll("delDir", 0755)
+	if err != nil {
 		t.Fatal(err)
 	}
 
 	m.ScanFolder("default")
 
-	conn := addFakeConn(m, device1)
-	conn.folder = "default"
+	if err = testFs.RemoveAll("delDir"); err != nil {
+		t.Fatal(err)
+	}
+
+	m.ScanFolder("default")
 
 	if fcfg, ok := m.cfg.Folder("default"); !ok || !fcfg.SharedWith(device1) {
 		t.Fatal("not shared with device1")

+ 19 - 33
lib/model/requests_test.go

@@ -18,7 +18,6 @@ import (
 	"time"
 
 	"github.com/syncthing/syncthing/lib/config"
-	"github.com/syncthing/syncthing/lib/db"
 	"github.com/syncthing/syncthing/lib/events"
 	"github.com/syncthing/syncthing/lib/fs"
 	"github.com/syncthing/syncthing/lib/ignore"
@@ -231,8 +230,6 @@ func TestRequestCreateTmpSymlink(t *testing.T) {
 }
 
 func TestRequestVersioningSymlinkAttack(t *testing.T) {
-	testOs := &fatalOs{t}
-
 	if runtime.GOOS == "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
 	// deleted symlink to escape
 
-	tmpDir := createTmpDir()
-	defer testOs.RemoveAll(tmpDir)
+	w, tmpDir := tmpDefaultWrapper()
+	defer func() {
+		os.RemoveAll(tmpDir)
+		os.Remove(w.ConfigPath())
+	}()
 
-	cfg := defaultCfgWrapper.RawCopy()
-	cfg.Folders[0] = config.NewFolderConfiguration(myID, "default", "default", fs.FilesystemTypeBasic, tmpDir)
-	cfg.Folders[0].Devices = []config.FolderDeviceConfiguration{
-		{DeviceID: myID},
-		{DeviceID: device1},
-	}
-	cfg.Folders[0].Versioning = config.VersioningConfiguration{
-		Type: "trashcan",
-	}
-	w := createTmpWrapper(cfg)
-	defer testOs.Remove(w.ConfigPath())
+	fcfg := w.FolderList()[0]
+	fcfg.Versioning = config.VersioningConfiguration{Type: "trashcan"}
+	w.SetFolder(fcfg)
 
-	db := db.OpenMemory()
-	m := NewModel(w, myID, "syncthing", "dev", db, nil)
-	m.AddFolder(cfg.Folders[0])
-	m.ServeBackground()
-	m.StartFolder("default")
+	m, fc := setupModelWithConnectionFromWrapper(w)
 	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
 	// we can escape to it
 	tmpdir, err := ioutil.TempDir("", "syncthing-test")
@@ -656,13 +639,11 @@ func TestRequestSymlinkWindows(t *testing.T) {
 		t.Skip("windows specific test")
 	}
 
-	testOs := &fatalOs{t}
-
 	m, fc, tmpDir, w := setupModelWithConnection()
 	defer func() {
 		m.Stop()
-		testOs.RemoveAll(tmpDir)
-		testOs.Remove(w.ConfigPath())
+		os.RemoveAll(tmpDir)
+		os.Remove(w.ConfigPath())
 	}()
 
 	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) {
 	tmpDir := createTmpDir()
 	return testFolderConfig(tmpDir), tmpDir
@@ -732,9 +720,7 @@ func testFolderConfig(path string) config.FolderConfiguration {
 }
 
 func setupModelWithConnection() (*Model, *fakeConnection, string, *config.Wrapper) {
-	w := createTmpWrapper(defaultCfgWrapper.RawCopy())
-	fcfg, tmpDir := testFolderConfigTmp()
-	w.SetFolder(fcfg)
+	w, tmpDir := tmpDefaultWrapper()
 	m, fc := setupModelWithConnectionFromWrapper(w)
 	return m, fc, tmpDir, w
 }

+ 9 - 9
lib/model/sharedpullerstate_test.go

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