mirror of
https://github.com/octoleo/syncthing.git
synced 2024-12-22 19:08:58 +00:00
lib/model: Run more tests in tmp dir (#5527)
This commit is contained in:
parent
4299af1c63
commit
5fd2cab102
@ -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()
|
||||||
// Update index
|
model.AddFolder(fcfg)
|
||||||
model.updateLocalsFromScanning("default", files)
|
|
||||||
return model
|
// Update index
|
||||||
}
|
if files != nil {
|
||||||
|
model.updateLocalsFromScanning("default", files)
|
||||||
|
}
|
||||||
|
|
||||||
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()
|
||||||
|
|
||||||
|
@ -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")
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user