예제 #1
0
func TestWalk(t *testing.T) {
	ignores := ignore.New(false)
	err := ignores.Load("testdata/.stignore")
	if err != nil {
		t.Fatal(err)
	}
	t.Log(ignores)

	w := Walker{
		Dir:       "testdata",
		BlockSize: 128 * 1024,
		Matcher:   ignores,
		Hashers:   2,
	}

	fchan, err := w.Walk()
	if err != nil {
		t.Fatal(err)
	}

	var tmp []protocol.FileInfo
	for f := range fchan {
		tmp = append(tmp, f)
	}
	sort.Sort(fileList(tmp))
	files := fileList(tmp).testfiles()

	if !reflect.DeepEqual(files, testdata) {
		t.Errorf("Walk returned unexpected data\nExpected: %v\nActual: %v", testdata, files)
	}
}
예제 #2
0
func TestWalk(t *testing.T) {
	ignores := ignore.New(false)
	err := ignores.Load("testdata/.stignore")
	if err != nil {
		t.Fatal(err)
	}
	t.Log(ignores)

	fchan, err := Walk(Config{
		Dir:       "testdata",
		BlockSize: 128 * 1024,
		Matcher:   ignores,
		Hashers:   2,
	})

	if err != nil {
		t.Fatal(err)
	}

	var tmp []protocol.FileInfo
	for f := range fchan {
		tmp = append(tmp, f)
	}
	sort.Sort(fileList(tmp))
	files := fileList(tmp).testfiles()

	if diff, equal := messagediff.PrettyDiff(testdata, files); !equal {
		t.Errorf("Walk returned unexpected data. Diff:\n%s", diff)
	}
}
예제 #3
0
func TestWalkSub(t *testing.T) {
	ignores := ignore.New(false)
	err := ignores.Load("testdata/.stignore")
	if err != nil {
		t.Fatal(err)
	}

	fchan, err := Walk(Config{
		Dir:       "testdata",
		Subs:      []string{"dir2"},
		BlockSize: 128 * 1024,
		Matcher:   ignores,
		Hashers:   2,
	})
	var files []protocol.FileInfo
	for f := range fchan {
		files = append(files, f)
	}
	if err != nil {
		t.Fatal(err)
	}

	// The directory contains two files, where one is ignored from a higher
	// level. We should see only the directory and one of the files.

	if len(files) != 2 {
		t.Fatalf("Incorrect length %d != 2", len(files))
	}
	if files[0].Name != "dir2" {
		t.Errorf("Incorrect file %v != dir2", files[0])
	}
	if files[1].Name != filepath.Join("dir2", "cfile") {
		t.Errorf("Incorrect file %v != dir2/cfile", files[1])
	}
}
예제 #4
0
func TestIssue3164(t *testing.T) {
	os.RemoveAll("testdata/issue3164")
	defer os.RemoveAll("testdata/issue3164")

	if err := os.MkdirAll("testdata/issue3164/oktodelete/foobar", 0777); err != nil {
		t.Fatal(err)
	}
	if err := ioutil.WriteFile("testdata/issue3164/oktodelete/foobar/file", []byte("Hello"), 0644); err != nil {
		t.Fatal(err)
	}
	if err := ioutil.WriteFile("testdata/issue3164/oktodelete/file", []byte("Hello"), 0644); err != nil {
		t.Fatal(err)
	}
	f := protocol.FileInfo{
		Name: "issue3164",
	}
	m := ignore.New(false)
	if err := m.Parse(bytes.NewBufferString("(?d)oktodelete"), ""); err != nil {
		t.Fatal(err)
	}

	fl := rwFolder{
		dbUpdates: make(chan dbUpdateJob, 1),
		dir:       "testdata",
	}

	fl.deleteDir(f, m)

	if _, err := os.Stat("testdata/issue3164"); !os.IsNotExist(err) {
		t.Fatal(err)
	}
}
예제 #5
0
// watchFolder installs inotify watcher for a folder, launches
// goroutine which receives changed items. It never exits.
func watchFolder(folder FolderConfiguration, stInput chan STEvent) {
	folderPath, err := realPath(expandTilde(folder.Path))
	if err != nil {
		Warning.Println("Failed to install inotify handler for "+folder.Label+".", err)
		informError("Failed to install inotify handler for " + folder.Label + ": " + err.Error())
		return
	}
	ignores := ignore.New(false)
	Trace.Println("Getting ignore patterns for " + folder.Label)
	ignores.Load(filepath.Join(folderPath, ".stignore"))
	fsInput := make(chan string)
	c := make(chan notify.EventInfo, maxFiles)
	ignoreTest := func(absolutePath string) bool {
		relPath := relativePath(absolutePath, folderPath)
		return ignores.Match(relPath).IsIgnored()
	}
	notify.SetDoNotWatch(ignoreTest)
	if err := notify.Watch(filepath.Join(folderPath, "..."), c, notify.All); err != nil {
		if strings.Contains(err.Error(), "too many open files") || strings.Contains(err.Error(), "no space left on device") {
			msg := "Failed to install inotify handler for " + folder.Label + ". Please increase inotify limits, see http://bit.ly/1PxkdUC for more information."
			Warning.Println(msg, err)
			informError(msg)
			return
		} else {
			Warning.Println("Failed to install inotify handler for "+folder.Label+".", err)
			informError("Failed to install inotify handler for " + folder.Label + ": " + err.Error())
			return
		}
	}
	defer notify.Stop(c)
	go accumulateChanges(debounceTimeout, folder.ID, folderPath, dirVsFiles, stInput, fsInput, informChange)
	OK.Println("Watching " + folder.Label + ": " + folderPath)
	if folder.RescanIntervalS < 1800 && delayScan <= 0 {
		OK.Printf("The rescan interval of folder %s can be increased to 3600 (an hour) or even 86400 (a day) as changes should be observed immediately while syncthing-inotify is running.", folder.Label)
	}
	// will we ever get out of this loop?
	for {
		evAbsolutePath := waitForEvent(c)
		Debug.Println("Change detected in: " + evAbsolutePath + " (could still be ignored)")
		evRelPath := relativePath(evAbsolutePath, folderPath)
		if ignores.Match(evRelPath).IsIgnored() {
			Debug.Println("Ignoring", evAbsolutePath)
			continue
		}
		Trace.Println("Change detected in: " + evAbsolutePath)
		fsInput <- evRelPath
	}
}
예제 #6
0
// Returns a function to test whether a path should be ignored.
// The directory given by the absolute path "folderPath" must contain the
// ".stignore" file. The returned function expects the path of the file to be
// tested relative to its folders root.
func createIgnoreFilter(folderPath string) func(relPath string) bool {
	ignores := ignore.New(false)
	ignores.Load(filepath.Join(folderPath, ".stignore"))
	return func(relPath string) bool {
		if strings.SplitN(relPath, pathSeparator, 2)[0] == versionFolder {
			return true
		}
		for _, ignorePrefix := range tempFilePrefixes {
			if strings.HasPrefix(filepath.Base(relPath), ignorePrefix) &&
				strings.HasSuffix(relPath, tempFileSuffix) {
				return true
			}
		}
		return ignores.Match(relPath).IsIgnored()
	}
}