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) } }
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) } }
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]) } }
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) } }
// 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 } }
// 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() } }