diff options
author | Jeff Gaston <jeffrygaston@google.com> | 2017-08-10 01:16:34 +0000 |
---|---|---|
committer | Jeff Gaston <jeffrygaston@google.com> | 2017-08-10 01:16:34 +0000 |
commit | d1abeb9d982b11fdf4047176d213acc8197c375f (patch) | |
tree | 63159a1dd05d904e64748a0d71356f4a4eafc901 /finder/finder_test.go | |
parent | b6d161bf16031e06fc8d532e35a53c73ad20f84f (diff) | |
download | build_soong-d1abeb9d982b11fdf4047176d213acc8197c375f.tar.gz build_soong-d1abeb9d982b11fdf4047176d213acc8197c375f.tar.bz2 build_soong-d1abeb9d982b11fdf4047176d213acc8197c375f.zip |
Revert "Cacheable, multithreaded finder."
This reverts commit b6d161bf16031e06fc8d532e35a53c73ad20f84f.
Reason for revert: New Build Breakage: aosp-master/sdk_mac @ 4260825
Change-Id: I8bda8c50c5e5c9f84621d11a4c15b168833bcd21
Diffstat (limited to 'finder/finder_test.go')
-rw-r--r-- | finder/finder_test.go | 1573 |
1 files changed, 0 insertions, 1573 deletions
diff --git a/finder/finder_test.go b/finder/finder_test.go deleted file mode 100644 index 60e5eb28..00000000 --- a/finder/finder_test.go +++ /dev/null @@ -1,1573 +0,0 @@ -// Copyright 2017 Google Inc. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package finder - -import ( - "fmt" - "log" - "path/filepath" - "reflect" - "testing" - - "sort" - - "io/ioutil" - - "android/soong/fs" - "runtime/debug" - "time" -) - -// some utils for tests to use -func newFs() *fs.MockFs { - return fs.NewMockFs(map[string][]byte{}) -} - -func newFinder(t *testing.T, filesystem *fs.MockFs, cacheParams CacheParams) *Finder { - cachePath := "/finder/finder-db" - cacheDir := filepath.Dir(cachePath) - filesystem.MkDirs(cacheDir) - if cacheParams.WorkingDirectory == "" { - cacheParams.WorkingDirectory = "/cwd" - } - - logger := log.New(ioutil.Discard, "", 0) - finder := New(cacheParams, filesystem, logger, cachePath) - return finder -} - -func finderWithSameParams(t *testing.T, original *Finder) *Finder { - return New( - original.cacheMetadata.Config.CacheParams, - original.filesystem, - original.logger, - original.DbPath) -} - -func write(t *testing.T, path string, content string, filesystem *fs.MockFs) { - parent := filepath.Dir(path) - filesystem.MkDirs(parent) - err := filesystem.WriteFile(path, []byte(content), 0777) - if err != nil { - t.Fatal(err.Error()) - } -} - -func create(t *testing.T, path string, filesystem *fs.MockFs) { - write(t, path, "hi", filesystem) -} - -func delete(t *testing.T, path string, filesystem *fs.MockFs) { - err := filesystem.Remove(path) - if err != nil { - t.Fatal(err.Error()) - } -} - -func removeAll(t *testing.T, path string, filesystem *fs.MockFs) { - err := filesystem.RemoveAll(path) - if err != nil { - t.Fatal(err.Error()) - } -} - -func move(t *testing.T, oldPath string, newPath string, filesystem *fs.MockFs) { - err := filesystem.Rename(oldPath, newPath) - if err != nil { - t.Fatal(err.Error()) - } -} - -func link(t *testing.T, newPath string, oldPath string, filesystem *fs.MockFs) { - parentPath := filepath.Dir(newPath) - err := filesystem.MkDirs(parentPath) - if err != nil { - t.Fatal(err.Error()) - } - err = filesystem.Symlink(oldPath, newPath) - if err != nil { - t.Fatal(err.Error()) - } -} -func read(t *testing.T, path string, filesystem *fs.MockFs) string { - reader, err := filesystem.Open(path) - if err != nil { - t.Fatalf(err.Error()) - } - bytes, err := ioutil.ReadAll(reader) - if err != nil { - t.Fatal(err.Error()) - } - return string(bytes) -} -func modTime(t *testing.T, path string, filesystem *fs.MockFs) time.Time { - stats, err := filesystem.Lstat(path) - if err != nil { - t.Fatal(err.Error()) - } - return stats.ModTime() -} -func setReadable(t *testing.T, path string, readable bool, filesystem *fs.MockFs) { - err := filesystem.SetReadable(path, readable) - if err != nil { - t.Fatal(err.Error()) - } -} -func fatal(t *testing.T, message string) { - t.Error(message) - debug.PrintStack() - t.FailNow() -} -func assertSameResponse(t *testing.T, actual []string, expected []string) { - sort.Strings(actual) - sort.Strings(expected) - if !reflect.DeepEqual(actual, expected) { - fatal( - t, - fmt.Sprintf( - "Expected Finder to return these %v paths:\n %v,\ninstead returned these %v paths: %v\n", - len(expected), expected, len(actual), actual), - ) - } -} - -func assertSameStatCalls(t *testing.T, actual []string, expected []string) { - sort.Strings(actual) - sort.Strings(expected) - - if !reflect.DeepEqual(actual, expected) { - fatal( - t, - fmt.Sprintf( - "Finder made incorrect Stat calls.\n"+ - "Actual:\n"+ - "%v\n"+ - "Expected:\n"+ - "%v\n"+ - "\n", - actual, expected), - ) - } -} -func assertSameReadDirCalls(t *testing.T, actual []string, expected []string) { - sort.Strings(actual) - sort.Strings(expected) - - if !reflect.DeepEqual(actual, expected) { - fatal( - t, - fmt.Sprintf( - "Finder made incorrect ReadDir calls.\n"+ - "Actual:\n"+ - "%v\n"+ - "Expected:\n"+ - "%v\n"+ - "\n", - actual, expected), - ) - } -} - -// runSimpleTests creates a few files, searches for findme.txt, and checks for the expected matches -func runSimpleTest(t *testing.T, existentPaths []string, expectedMatches []string) { - filesystem := newFs() - root := "/tmp" - filesystem.MkDirs(root) - for _, path := range existentPaths { - create(t, filepath.Join(root, path), filesystem) - } - - finder := newFinder(t, - filesystem, - CacheParams{ - "/cwd", - []string{root}, - nil, - nil, - []string{"findme.txt", "skipme.txt"}, - }, - ) - defer finder.Shutdown() - - foundPaths := finder.FindNamedAt(root, "findme.txt") - absoluteMatches := []string{} - for i := range expectedMatches { - absoluteMatches = append(absoluteMatches, filepath.Join(root, expectedMatches[i])) - } - assertSameResponse(t, foundPaths, absoluteMatches) -} - -// end of utils, start of individual tests - -func TestSingleFile(t *testing.T) { - runSimpleTest(t, - []string{"findme.txt"}, - []string{"findme.txt"}, - ) -} - -func TestIncludeFiles(t *testing.T) { - runSimpleTest(t, - []string{"findme.txt", "skipme.txt"}, - []string{"findme.txt"}, - ) -} - -func TestNestedDirectories(t *testing.T) { - runSimpleTest(t, - []string{"findme.txt", "skipme.txt", "subdir/findme.txt", "subdir/skipme.txt"}, - []string{"findme.txt", "subdir/findme.txt"}, - ) -} - -func TestEmptyDirectory(t *testing.T) { - runSimpleTest(t, - []string{}, - []string{}, - ) -} - -func TestEmptyPath(t *testing.T) { - filesystem := newFs() - root := "/tmp" - create(t, filepath.Join(root, "findme.txt"), filesystem) - - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{root}, - IncludeFiles: []string{"findme.txt", "skipme.txt"}, - }, - ) - defer finder.Shutdown() - - foundPaths := finder.FindNamedAt("", "findme.txt") - - assertSameResponse(t, foundPaths, []string{}) -} - -func TestFilesystemRoot(t *testing.T) { - filesystem := newFs() - root := "/" - createdPath := "/findme.txt" - create(t, createdPath, filesystem) - - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{root}, - IncludeFiles: []string{"findme.txt", "skipme.txt"}, - }, - ) - defer finder.Shutdown() - - foundPaths := finder.FindNamedAt(root, "findme.txt") - - assertSameResponse(t, foundPaths, []string{createdPath}) -} - -func TestNonexistentPath(t *testing.T) { - filesystem := newFs() - create(t, "/tmp/findme.txt", filesystem) - - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/tmp/IDontExist"}, - IncludeFiles: []string{"findme.txt", "skipme.txt"}, - }, - ) - defer finder.Shutdown() - - foundPaths := finder.FindNamedAt("/tmp/IAlsoDontExist", "findme.txt") - - assertSameResponse(t, foundPaths, []string{}) -} - -func TestExcludeDirs(t *testing.T) { - filesystem := newFs() - create(t, "/tmp/exclude/findme.txt", filesystem) - create(t, "/tmp/exclude/subdir/findme.txt", filesystem) - create(t, "/tmp/subdir/exclude/findme.txt", filesystem) - create(t, "/tmp/subdir/subdir/findme.txt", filesystem) - create(t, "/tmp/subdir/findme.txt", filesystem) - create(t, "/tmp/findme.txt", filesystem) - - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/tmp"}, - ExcludeDirs: []string{"exclude"}, - IncludeFiles: []string{"findme.txt", "skipme.txt"}, - }, - ) - defer finder.Shutdown() - - foundPaths := finder.FindNamedAt("/tmp", "findme.txt") - - assertSameResponse(t, foundPaths, - []string{"/tmp/findme.txt", - "/tmp/subdir/findme.txt", - "/tmp/subdir/subdir/findme.txt"}) -} - -func TestPruneFiles(t *testing.T) { - filesystem := newFs() - create(t, "/tmp/out/findme.txt", filesystem) - create(t, "/tmp/out/.ignore-out-dir", filesystem) - create(t, "/tmp/out/child/findme.txt", filesystem) - - create(t, "/tmp/out2/.ignore-out-dir", filesystem) - create(t, "/tmp/out2/sub/findme.txt", filesystem) - - create(t, "/tmp/findme.txt", filesystem) - create(t, "/tmp/include/findme.txt", filesystem) - - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/tmp"}, - PruneFiles: []string{".ignore-out-dir"}, - IncludeFiles: []string{"findme.txt"}, - }, - ) - defer finder.Shutdown() - - foundPaths := finder.FindNamedAt("/tmp", "findme.txt") - - assertSameResponse(t, foundPaths, - []string{"/tmp/findme.txt", - "/tmp/include/findme.txt"}) -} - -func TestRootDir(t *testing.T) { - filesystem := newFs() - create(t, "/tmp/a/findme.txt", filesystem) - create(t, "/tmp/a/subdir/findme.txt", filesystem) - create(t, "/tmp/b/findme.txt", filesystem) - create(t, "/tmp/b/subdir/findme.txt", filesystem) - - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/tmp/a"}, - IncludeFiles: []string{"findme.txt"}, - }, - ) - defer finder.Shutdown() - - foundPaths := finder.FindNamedAt("/tmp/a", "findme.txt") - - assertSameResponse(t, foundPaths, - []string{"/tmp/a/findme.txt", - "/tmp/a/subdir/findme.txt"}) -} - -func TestUncachedDir(t *testing.T) { - filesystem := newFs() - create(t, "/tmp/a/findme.txt", filesystem) - create(t, "/tmp/a/subdir/findme.txt", filesystem) - create(t, "/tmp/b/findme.txt", filesystem) - create(t, "/tmp/b/subdir/findme.txt", filesystem) - - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/IDoNotExist"}, - IncludeFiles: []string{"findme.txt"}, - }, - ) - - foundPaths := finder.FindNamedAt("/tmp/a", "findme.txt") - // If the caller queries for a file that is in the cache, then computing the - // correct answer won't be fast, and it would be easy for the caller to - // fail to notice its slowness. Instead, we only ever search the cache for files - // to return, which enforces that we can determine which files will be - // interesting upfront. - assertSameResponse(t, foundPaths, []string{}) - - finder.Shutdown() -} - -func TestSearchingForFilesExcludedFromCache(t *testing.T) { - // setup filesystem - filesystem := newFs() - create(t, "/tmp/findme.txt", filesystem) - create(t, "/tmp/a/findme.txt", filesystem) - create(t, "/tmp/a/misc.txt", filesystem) - - // set up the finder and run it - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/tmp"}, - IncludeFiles: []string{"findme.txt"}, - }, - ) - foundPaths := finder.FindNamedAt("/tmp", "misc.txt") - // If the caller queries for a file that is in the cache, then computing the - // correct answer won't be fast, and it would be easy for the caller to - // fail to notice its slowness. Instead, we only ever search the cache for files - // to return, which enforces that we can determine which files will be - // interesting upfront. - assertSameResponse(t, foundPaths, []string{}) - - finder.Shutdown() -} - -func TestRelativeFilePaths(t *testing.T) { - filesystem := newFs() - - create(t, "/tmp/ignore/hi.txt", filesystem) - create(t, "/tmp/include/hi.txt", filesystem) - create(t, "/cwd/hi.txt", filesystem) - create(t, "/cwd/a/hi.txt", filesystem) - create(t, "/cwd/a/a/hi.txt", filesystem) - - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/cwd", "/tmp/include"}, - IncludeFiles: []string{"hi.txt"}, - }, - ) - defer finder.Shutdown() - - foundPaths := finder.FindNamedAt("a", "hi.txt") - assertSameResponse(t, foundPaths, - []string{"a/hi.txt", - "a/a/hi.txt"}) - - foundPaths = finder.FindNamedAt("/tmp/include", "hi.txt") - assertSameResponse(t, foundPaths, []string{"/tmp/include/hi.txt"}) - - foundPaths = finder.FindNamedAt(".", "hi.txt") - assertSameResponse(t, foundPaths, - []string{"hi.txt", - "a/hi.txt", - "a/a/hi.txt"}) - - foundPaths = finder.FindNamedAt("/tmp/include", "hi.txt") - assertSameResponse(t, foundPaths, []string{"/tmp/include/hi.txt"}) -} - -// have to run this test with the race-detector (`go test -race src/android/soong/finder/*.go`) -// for there to be much chance of the test actually detecting any error that may be present -func TestRootDirsContainedInOtherRootDirs(t *testing.T) { - filesystem := newFs() - - create(t, "/tmp/a/b/c/d/e/f/g/h/i/j/findme.txt", filesystem) - - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/", "/a/b/c", "/a/b/c/d/e/f", "/a/b/c/d/e/f/g/h/i"}, - IncludeFiles: []string{"findme.txt"}, - }, - ) - defer finder.Shutdown() - - foundPaths := finder.FindNamedAt("/tmp/a", "findme.txt") - - assertSameResponse(t, foundPaths, - []string{"/tmp/a/b/c/d/e/f/g/h/i/j/findme.txt"}) -} - -func TestFindFirst(t *testing.T) { - filesystem := newFs() - create(t, "/tmp/a/hi.txt", filesystem) - create(t, "/tmp/b/hi.txt", filesystem) - create(t, "/tmp/b/a/hi.txt", filesystem) - - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/tmp"}, - IncludeFiles: []string{"hi.txt"}, - }, - ) - defer finder.Shutdown() - - foundPaths := finder.FindFirstNamed("hi.txt") - - assertSameResponse(t, foundPaths, - []string{"/tmp/a/hi.txt", - "/tmp/b/hi.txt"}, - ) -} - -func TestConcurrentFindSameDirectory(t *testing.T) { - filesystem := newFs() - - // create a bunch of files and directories - paths := []string{} - for i := 0; i < 10; i++ { - parentDir := fmt.Sprintf("/tmp/%v", i) - for j := 0; j < 10; j++ { - filePath := filepath.Join(parentDir, fmt.Sprintf("%v/findme.txt", j)) - paths = append(paths, filePath) - } - } - sort.Strings(paths) - for _, path := range paths { - create(t, path, filesystem) - } - - // set up a finder - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/tmp"}, - IncludeFiles: []string{"findme.txt"}, - }, - ) - defer finder.Shutdown() - - numTests := 20 - results := make(chan []string, numTests) - // make several parallel calls to the finder - for i := 0; i < numTests; i++ { - go func() { - foundPaths := finder.FindNamedAt("/tmp", "findme.txt") - results <- foundPaths - }() - } - - // check that each response was correct - for i := 0; i < numTests; i++ { - foundPaths := <-results - assertSameResponse(t, foundPaths, paths) - } -} - -func TestConcurrentFindDifferentDirectories(t *testing.T) { - filesystem := newFs() - - // create a bunch of files and directories - allFiles := []string{} - numSubdirs := 10 - rootPaths := []string{} - queryAnswers := [][]string{} - for i := 0; i < numSubdirs; i++ { - parentDir := fmt.Sprintf("/tmp/%v", i) - rootPaths = append(rootPaths, parentDir) - queryAnswers = append(queryAnswers, []string{}) - for j := 0; j < 10; j++ { - filePath := filepath.Join(parentDir, fmt.Sprintf("%v/findme.txt", j)) - queryAnswers[i] = append(queryAnswers[i], filePath) - allFiles = append(allFiles, filePath) - } - sort.Strings(queryAnswers[i]) - } - sort.Strings(allFiles) - for _, path := range allFiles { - create(t, path, filesystem) - } - - // set up a finder - finder := newFinder( - t, - filesystem, - - CacheParams{ - RootDirs: []string{"/tmp"}, - IncludeFiles: []string{"findme.txt"}, - }, - ) - defer finder.Shutdown() - - type testRun struct { - path string - foundMatches []string - correctMatches []string - } - - numTests := numSubdirs + 1 - testRuns := make(chan testRun, numTests) - - searchAt := func(path string, correctMatches []string) { - foundPaths := finder.FindNamedAt(path, "findme.txt") - testRuns <- testRun{path, foundPaths, correctMatches} - } - - // make several parallel calls to the finder - go searchAt("/tmp", allFiles) - for i := 0; i < len(rootPaths); i++ { - go searchAt(rootPaths[i], queryAnswers[i]) - } - - // check that each response was correct - for i := 0; i < numTests; i++ { - testRun := <-testRuns - assertSameResponse(t, testRun.foundMatches, testRun.correctMatches) - } -} - -func TestStrangelyFormattedPaths(t *testing.T) { - filesystem := newFs() - - create(t, "/tmp/findme.txt", filesystem) - create(t, "/tmp/a/findme.txt", filesystem) - create(t, "/tmp/b/findme.txt", filesystem) - - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"//tmp//a//.."}, - IncludeFiles: []string{"findme.txt"}, - }, - ) - defer finder.Shutdown() - - foundPaths := finder.FindNamedAt("//tmp//a//..", "findme.txt") - - assertSameResponse(t, foundPaths, - []string{"/tmp/a/findme.txt", - "/tmp/b/findme.txt", - "/tmp/findme.txt"}) -} - -func TestCorruptedCacheHeader(t *testing.T) { - filesystem := newFs() - - create(t, "/tmp/findme.txt", filesystem) - create(t, "/tmp/a/findme.txt", filesystem) - write(t, "/finder/finder-db", "sample header", filesystem) - - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/tmp"}, - IncludeFiles: []string{"findme.txt"}, - }, - ) - defer finder.Shutdown() - - foundPaths := finder.FindNamedAt("/tmp", "findme.txt") - - assertSameResponse(t, foundPaths, - []string{"/tmp/a/findme.txt", - "/tmp/findme.txt"}) -} - -func TestCanUseCache(t *testing.T) { - // setup filesystem - filesystem := newFs() - create(t, "/tmp/findme.txt", filesystem) - create(t, "/tmp/a/findme.txt", filesystem) - - // run the first finder - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/tmp"}, - IncludeFiles: []string{"findme.txt"}, - }, - ) - foundPaths := finder.FindNamedAt("/tmp", "findme.txt") - // check the response of the first finder - correctResponse := []string{"/tmp/a/findme.txt", - "/tmp/findme.txt"} - assertSameResponse(t, foundPaths, correctResponse) - finder.Shutdown() - - // check results - cacheText := read(t, finder.DbPath, filesystem) - if len(cacheText) < 1 { - t.Fatalf("saved cache db is empty\n") - } - if len(filesystem.StatCalls) == 0 { - t.Fatal("No Stat calls recorded by mock filesystem") - } - if len(filesystem.ReadDirCalls) == 0 { - t.Fatal("No ReadDir calls recorded by filesystem") - } - statCalls := filesystem.StatCalls - filesystem.ClearMetrics() - - // run the second finder - finder2 := finderWithSameParams(t, finder) - foundPaths = finder2.FindNamedAt("/tmp", "findme.txt") - // check results - assertSameReadDirCalls(t, filesystem.ReadDirCalls, []string{}) - assertSameReadDirCalls(t, filesystem.StatCalls, statCalls) - - finder2.Shutdown() -} - -func TestCorruptedCacheBody(t *testing.T) { - // setup filesystem - filesystem := newFs() - create(t, "/tmp/findme.txt", filesystem) - create(t, "/tmp/a/findme.txt", filesystem) - - // run the first finder - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/tmp"}, - IncludeFiles: []string{"findme.txt"}, - }, - ) - foundPaths := finder.FindNamedAt("/tmp", "findme.txt") - finder.Shutdown() - - // check the response of the first finder - correctResponse := []string{"/tmp/a/findme.txt", - "/tmp/findme.txt"} - assertSameResponse(t, foundPaths, correctResponse) - numStatCalls := len(filesystem.StatCalls) - numReadDirCalls := len(filesystem.ReadDirCalls) - - // load the cache file, corrupt it, and save it - cacheReader, err := filesystem.Open(finder.DbPath) - if err != nil { - t.Fatal(err) - } - cacheData, err := ioutil.ReadAll(cacheReader) - if err != nil { - t.Fatal(err) - } - cacheData = append(cacheData, []byte("DontMindMe")...) - filesystem.WriteFile(finder.DbPath, cacheData, 0777) - filesystem.ClearMetrics() - - // run the second finder - finder2 := finderWithSameParams(t, finder) - foundPaths = finder2.FindNamedAt("/tmp", "findme.txt") - // check results - assertSameResponse(t, foundPaths, correctResponse) - numNewStatCalls := len(filesystem.StatCalls) - numNewReadDirCalls := len(filesystem.ReadDirCalls) - // It's permissable to make more Stat calls with a corrupted cache because - // the Finder may restart once it detects corruption. - // However, it may have already issued many Stat calls. - // Because a corrupted db is not expected to be a common (or even a supported case), - // we don't care to optimize it and don't cache the already-issued Stat calls - if numNewReadDirCalls < numReadDirCalls { - t.Fatalf( - "Finder made fewer ReadDir calls with a corrupted cache (%v calls) than with no cache"+ - " (%v calls)", - numNewReadDirCalls, numReadDirCalls) - } - if numNewStatCalls < numStatCalls { - t.Fatalf( - "Finder made fewer Stat calls with a corrupted cache (%v calls) than with no cache (%v calls)", - numNewStatCalls, numStatCalls) - } - finder2.Shutdown() -} - -func TestStatCalls(t *testing.T) { - // setup filesystem - filesystem := newFs() - create(t, "/tmp/a/findme.txt", filesystem) - - // run finder - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/tmp"}, - IncludeFiles: []string{"findme.txt"}, - }, - ) - foundPaths := finder.FindNamedAt("/tmp", "findme.txt") - finder.Shutdown() - - // check response - assertSameResponse(t, foundPaths, []string{"/tmp/a/findme.txt"}) - assertSameStatCalls(t, filesystem.StatCalls, []string{"/tmp", "/tmp/a"}) - assertSameReadDirCalls(t, filesystem.ReadDirCalls, []string{"/tmp", "/tmp/a"}) -} - -func TestFileAdded(t *testing.T) { - // setup filesystem - filesystem := newFs() - create(t, "/tmp/ignoreme.txt", filesystem) - create(t, "/tmp/a/findme.txt", filesystem) - create(t, "/tmp/b/ignore.txt", filesystem) - create(t, "/tmp/b/c/nope.txt", filesystem) - create(t, "/tmp/b/c/d/irrelevant.txt", filesystem) - - // run the first finder - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/tmp"}, - IncludeFiles: []string{"findme.txt"}, - }, - ) - foundPaths := finder.FindNamedAt("/tmp", "findme.txt") - filesystem.Clock.Tick() - finder.Shutdown() - // check the response of the first finder - assertSameResponse(t, foundPaths, []string{"/tmp/a/findme.txt"}) - - // modify the filesystem - filesystem.Clock.Tick() - create(t, "/tmp/b/c/findme.txt", filesystem) - filesystem.Clock.Tick() - filesystem.ClearMetrics() - - // run the second finder - finder2 := finderWithSameParams(t, finder) - foundPaths = finder2.FindNamedAt("/tmp", "findme.txt") - - // check results - assertSameResponse(t, foundPaths, []string{"/tmp/a/findme.txt", "/tmp/b/c/findme.txt"}) - assertSameStatCalls(t, filesystem.StatCalls, []string{"/tmp", "/tmp/a", "/tmp/b", "/tmp/b/c", "/tmp/b/c/d"}) - assertSameReadDirCalls(t, filesystem.ReadDirCalls, []string{"/tmp/b/c"}) - finder2.Shutdown() - -} - -func TestDirectoriesAdded(t *testing.T) { - // setup filesystem - filesystem := newFs() - create(t, "/tmp/ignoreme.txt", filesystem) - create(t, "/tmp/a/findme.txt", filesystem) - create(t, "/tmp/b/ignore.txt", filesystem) - create(t, "/tmp/b/c/nope.txt", filesystem) - create(t, "/tmp/b/c/d/irrelevant.txt", filesystem) - - // run the first finder - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/tmp"}, - IncludeFiles: []string{"findme.txt"}, - }, - ) - foundPaths := finder.FindNamedAt("/tmp", "findme.txt") - finder.Shutdown() - // check the response of the first finder - assertSameResponse(t, foundPaths, []string{"/tmp/a/findme.txt"}) - - // modify the filesystem - filesystem.Clock.Tick() - create(t, "/tmp/b/c/new/findme.txt", filesystem) - create(t, "/tmp/b/c/new/new2/findme.txt", filesystem) - create(t, "/tmp/b/c/new/new2/ignoreme.txt", filesystem) - filesystem.ClearMetrics() - - // run the second finder - finder2 := finderWithSameParams(t, finder) - foundPaths = finder2.FindNamedAt("/tmp", "findme.txt") - - // check results - assertSameResponse(t, foundPaths, - []string{"/tmp/a/findme.txt", "/tmp/b/c/new/findme.txt", "/tmp/b/c/new/new2/findme.txt"}) - assertSameStatCalls(t, filesystem.StatCalls, - []string{"/tmp", "/tmp/a", "/tmp/b", "/tmp/b/c", "/tmp/b/c/d", "/tmp/b/c/new", "/tmp/b/c/new/new2"}) - assertSameReadDirCalls(t, filesystem.ReadDirCalls, []string{"/tmp/b/c", "/tmp/b/c/new", "/tmp/b/c/new/new2"}) - - finder2.Shutdown() -} - -func TestDirectoryAndSubdirectoryBothUpdated(t *testing.T) { - // setup filesystem - filesystem := newFs() - create(t, "/tmp/hi1.txt", filesystem) - create(t, "/tmp/a/hi1.txt", filesystem) - - // run the first finder - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/tmp"}, - IncludeFiles: []string{"hi1.txt", "hi2.txt"}, - }, - ) - foundPaths := finder.FindNamedAt("/tmp", "hi1.txt") - finder.Shutdown() - // check the response of the first finder - assertSameResponse(t, foundPaths, []string{"/tmp/hi1.txt", "/tmp/a/hi1.txt"}) - - // modify the filesystem - filesystem.Clock.Tick() - create(t, "/tmp/hi2.txt", filesystem) - create(t, "/tmp/a/hi2.txt", filesystem) - filesystem.ClearMetrics() - - // run the second finder - finder2 := finderWithSameParams(t, finder) - foundPaths = finder2.FindAll() - - // check results - assertSameResponse(t, foundPaths, - []string{"/tmp/hi1.txt", "/tmp/hi2.txt", "/tmp/a/hi1.txt", "/tmp/a/hi2.txt"}) - assertSameStatCalls(t, filesystem.StatCalls, - []string{"/tmp", "/tmp/a"}) - assertSameReadDirCalls(t, filesystem.ReadDirCalls, []string{"/tmp", "/tmp/a"}) - - finder2.Shutdown() -} - -func TestFileDeleted(t *testing.T) { - // setup filesystem - filesystem := newFs() - create(t, "/tmp/ignoreme.txt", filesystem) - create(t, "/tmp/a/findme.txt", filesystem) - create(t, "/tmp/b/findme.txt", filesystem) - create(t, "/tmp/b/c/nope.txt", filesystem) - create(t, "/tmp/b/c/d/irrelevant.txt", filesystem) - - // run the first finder - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/tmp"}, - IncludeFiles: []string{"findme.txt"}, - }, - ) - foundPaths := finder.FindNamedAt("/tmp", "findme.txt") - finder.Shutdown() - // check the response of the first finder - assertSameResponse(t, foundPaths, []string{"/tmp/a/findme.txt", "/tmp/b/findme.txt"}) - - // modify the filesystem - filesystem.Clock.Tick() - delete(t, "/tmp/b/findme.txt", filesystem) - filesystem.ClearMetrics() - - // run the second finder - finder2 := finderWithSameParams(t, finder) - foundPaths = finder2.FindNamedAt("/tmp", "findme.txt") - - // check results - assertSameResponse(t, foundPaths, []string{"/tmp/a/findme.txt"}) - assertSameStatCalls(t, filesystem.StatCalls, []string{"/tmp", "/tmp/a", "/tmp/b", "/tmp/b/c", "/tmp/b/c/d"}) - assertSameReadDirCalls(t, filesystem.ReadDirCalls, []string{"/tmp/b"}) - - finder2.Shutdown() -} - -func TestDirectoriesDeleted(t *testing.T) { - // setup filesystem - filesystem := newFs() - create(t, "/tmp/findme.txt", filesystem) - create(t, "/tmp/a/findme.txt", filesystem) - create(t, "/tmp/a/1/findme.txt", filesystem) - create(t, "/tmp/a/1/2/findme.txt", filesystem) - create(t, "/tmp/b/findme.txt", filesystem) - - // run the first finder - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/tmp"}, - IncludeFiles: []string{"findme.txt"}, - }, - ) - foundPaths := finder.FindNamedAt("/tmp", "findme.txt") - finder.Shutdown() - // check the response of the first finder - assertSameResponse(t, foundPaths, - []string{"/tmp/findme.txt", - "/tmp/a/findme.txt", - "/tmp/a/1/findme.txt", - "/tmp/a/1/2/findme.txt", - "/tmp/b/findme.txt"}) - - // modify the filesystem - filesystem.Clock.Tick() - removeAll(t, "/tmp/a/1", filesystem) - filesystem.ClearMetrics() - - // run the second finder - finder2 := finderWithSameParams(t, finder) - foundPaths = finder2.FindNamedAt("/tmp", "findme.txt") - - // check results - assertSameResponse(t, foundPaths, - []string{"/tmp/findme.txt", "/tmp/a/findme.txt", "/tmp/b/findme.txt"}) - // Technically, we don't care whether /tmp/a/1/2 gets Statted or gets skipped - // if the Finder detects the nonexistence of /tmp/a/1 - // However, when resuming from cache, we don't want the Finder to necessarily wait - // to stat a directory until after statting its parent. - // So here we just include /tmp/a/1/2 in the list. - // The Finder is currently implemented to always restat every dir and - // to not short-circuit due to nonexistence of parents (but it will remove - // missing dirs from the cache for next time) - assertSameStatCalls(t, filesystem.StatCalls, - []string{"/tmp", "/tmp/a", "/tmp/a/1", "/tmp/a/1/2", "/tmp/b"}) - assertSameReadDirCalls(t, filesystem.ReadDirCalls, []string{"/tmp/a"}) - - finder2.Shutdown() -} - -func TestDirectoriesMoved(t *testing.T) { - // setup filesystem - filesystem := newFs() - create(t, "/tmp/findme.txt", filesystem) - create(t, "/tmp/a/findme.txt", filesystem) - create(t, "/tmp/a/1/findme.txt", filesystem) - create(t, "/tmp/a/1/2/findme.txt", filesystem) - create(t, "/tmp/b/findme.txt", filesystem) - - // run the first finder - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/tmp"}, - IncludeFiles: []string{"findme.txt"}, - }, - ) - foundPaths := finder.FindNamedAt("/tmp", "findme.txt") - finder.Shutdown() - // check the response of the first finder - assertSameResponse(t, foundPaths, - []string{"/tmp/findme.txt", - "/tmp/a/findme.txt", - "/tmp/a/1/findme.txt", - "/tmp/a/1/2/findme.txt", - "/tmp/b/findme.txt"}) - - // modify the filesystem - filesystem.Clock.Tick() - move(t, "/tmp/a", "/tmp/c", filesystem) - filesystem.ClearMetrics() - - // run the second finder - finder2 := finderWithSameParams(t, finder) - foundPaths = finder2.FindNamedAt("/tmp", "findme.txt") - - // check results - assertSameResponse(t, foundPaths, - []string{"/tmp/findme.txt", - "/tmp/b/findme.txt", - "/tmp/c/findme.txt", - "/tmp/c/1/findme.txt", - "/tmp/c/1/2/findme.txt"}) - // Technically, we don't care whether /tmp/a/1/2 gets Statted or gets skipped - // if the Finder detects the nonexistence of /tmp/a/1 - // However, when resuming from cache, we don't want the Finder to necessarily wait - // to stat a directory until after statting its parent. - // So here we just include /tmp/a/1/2 in the list. - // The Finder is currently implemented to always restat every dir and - // to not short-circuit due to nonexistence of parents (but it will remove - // missing dirs from the cache for next time) - assertSameStatCalls(t, filesystem.StatCalls, - []string{"/tmp", "/tmp/a", "/tmp/a/1", "/tmp/a/1/2", "/tmp/b", "/tmp/c", "/tmp/c/1", "/tmp/c/1/2"}) - assertSameReadDirCalls(t, filesystem.ReadDirCalls, []string{"/tmp", "/tmp/c", "/tmp/c/1", "/tmp/c/1/2"}) - finder2.Shutdown() -} - -func TestDirectoriesSwapped(t *testing.T) { - // setup filesystem - filesystem := newFs() - create(t, "/tmp/findme.txt", filesystem) - create(t, "/tmp/a/findme.txt", filesystem) - create(t, "/tmp/a/1/findme.txt", filesystem) - create(t, "/tmp/a/1/2/findme.txt", filesystem) - create(t, "/tmp/b/findme.txt", filesystem) - - // run the first finder - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/tmp"}, - IncludeFiles: []string{"findme.txt"}, - }, - ) - foundPaths := finder.FindNamedAt("/tmp", "findme.txt") - finder.Shutdown() - // check the response of the first finder - assertSameResponse(t, foundPaths, - []string{"/tmp/findme.txt", - "/tmp/a/findme.txt", - "/tmp/a/1/findme.txt", - "/tmp/a/1/2/findme.txt", - "/tmp/b/findme.txt"}) - - // modify the filesystem - filesystem.Clock.Tick() - move(t, "/tmp/a", "/tmp/temp", filesystem) - move(t, "/tmp/b", "/tmp/a", filesystem) - move(t, "/tmp/temp", "/tmp/b", filesystem) - filesystem.ClearMetrics() - - // run the second finder - finder2 := finderWithSameParams(t, finder) - foundPaths = finder2.FindNamedAt("/tmp", "findme.txt") - - // check results - assertSameResponse(t, foundPaths, - []string{"/tmp/findme.txt", - "/tmp/a/findme.txt", - "/tmp/b/findme.txt", - "/tmp/b/1/findme.txt", - "/tmp/b/1/2/findme.txt"}) - // Technically, we don't care whether /tmp/a/1/2 gets Statted or gets skipped - // if the Finder detects the nonexistence of /tmp/a/1 - // However, when resuming from cache, we don't want the Finder to necessarily wait - // to stat a directory until after statting its parent. - // So here we just include /tmp/a/1/2 in the list. - // The Finder is currently implemented to always restat every dir and - // to not short-circuit due to nonexistence of parents (but it will remove - // missing dirs from the cache for next time) - assertSameStatCalls(t, filesystem.StatCalls, - []string{"/tmp", "/tmp/a", "/tmp/a/1", "/tmp/a/1/2", "/tmp/b", "/tmp/b/1", "/tmp/b/1/2"}) - assertSameReadDirCalls(t, filesystem.ReadDirCalls, []string{"/tmp", "/tmp/a", "/tmp/b", "/tmp/b/1", "/tmp/b/1/2"}) - finder2.Shutdown() -} - -// runFsReplacementTest tests a change modifying properties of the filesystem itself: -// runFsReplacementTest tests changing the user, the hostname, or the device number -// runFsReplacementTest is a helper method called by other tests -func runFsReplacementTest(t *testing.T, fs1 *fs.MockFs, fs2 *fs.MockFs) { - // setup fs1 - create(t, "/tmp/findme.txt", fs1) - create(t, "/tmp/a/findme.txt", fs1) - create(t, "/tmp/a/a/findme.txt", fs1) - - // setup fs2 to have the same directories but different files - create(t, "/tmp/findme.txt", fs2) - create(t, "/tmp/a/findme.txt", fs2) - create(t, "/tmp/a/a/ignoreme.txt", fs2) - create(t, "/tmp/a/b/findme.txt", fs2) - - // run the first finder - finder := newFinder( - t, - fs1, - CacheParams{ - RootDirs: []string{"/tmp"}, - IncludeFiles: []string{"findme.txt"}, - }, - ) - foundPaths := finder.FindNamedAt("/tmp", "findme.txt") - finder.Shutdown() - // check the response of the first finder - assertSameResponse(t, foundPaths, - []string{"/tmp/findme.txt", "/tmp/a/findme.txt", "/tmp/a/a/findme.txt"}) - - // copy the cache data from the first filesystem to the second - cacheContent := read(t, finder.DbPath, fs1) - write(t, finder.DbPath, cacheContent, fs2) - - // run the second finder, with the same config and same cache contents but a different filesystem - finder2 := newFinder( - t, - fs2, - CacheParams{ - RootDirs: []string{"/tmp"}, - IncludeFiles: []string{"findme.txt"}, - }, - ) - foundPaths = finder2.FindNamedAt("/tmp", "findme.txt") - - // check results - assertSameResponse(t, foundPaths, - []string{"/tmp/findme.txt", "/tmp/a/findme.txt", "/tmp/a/b/findme.txt"}) - assertSameStatCalls(t, fs2.StatCalls, - []string{"/tmp", "/tmp/a", "/tmp/a/a", "/tmp/a/b"}) - assertSameReadDirCalls(t, fs2.ReadDirCalls, - []string{"/tmp", "/tmp/a", "/tmp/a/a", "/tmp/a/b"}) - finder2.Shutdown() -} - -func TestChangeOfDevice(t *testing.T) { - fs1 := newFs() - // not as fine-grained mounting controls as a real filesystem, but should be adequate - fs1.SetDeviceNumber(0) - - fs2 := newFs() - fs2.SetDeviceNumber(1) - - runFsReplacementTest(t, fs1, fs2) -} - -func TestChangeOfUserOrHost(t *testing.T) { - fs1 := newFs() - fs1.SetViewId("me@here") - - fs2 := newFs() - fs2.SetViewId("you@there") - - runFsReplacementTest(t, fs1, fs2) -} - -func TestConsistentCacheOrdering(t *testing.T) { - // setup filesystem - filesystem := newFs() - for i := 0; i < 5; i++ { - create(t, fmt.Sprintf("/tmp/%v/findme.txt", i), filesystem) - } - - // run the first finder - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/tmp"}, - IncludeFiles: []string{"findme.txt"}, - }, - ) - finder.FindNamedAt("/tmp", "findme.txt") - finder.Shutdown() - - // read db file - string1 := read(t, finder.DbPath, filesystem) - - err := filesystem.Remove(finder.DbPath) - if err != nil { - t.Fatal(err) - } - - // run another finder - finder2 := finderWithSameParams(t, finder) - finder2.FindNamedAt("/tmp", "findme.txt") - finder2.Shutdown() - - string2 := read(t, finder.DbPath, filesystem) - - if string1 != string2 { - t.Errorf("Running Finder twice generated two dbs not having identical contents.\n"+ - "Content of first file:\n"+ - "\n"+ - "%v"+ - "\n"+ - "\n"+ - "Content of second file:\n"+ - "\n"+ - "%v\n"+ - "\n", - string1, - string2, - ) - } - -} - -func TestNumSyscallsOfSecondFind(t *testing.T) { - // setup filesystem - filesystem := newFs() - create(t, "/tmp/findme.txt", filesystem) - create(t, "/tmp/a/findme.txt", filesystem) - create(t, "/tmp/a/misc.txt", filesystem) - - // set up the finder and run it once - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/tmp"}, - IncludeFiles: []string{"findme.txt"}, - }, - ) - foundPaths := finder.FindNamedAt("/tmp", "findme.txt") - assertSameResponse(t, foundPaths, []string{"/tmp/findme.txt", "/tmp/a/findme.txt"}) - - filesystem.ClearMetrics() - - // run the finder again and confirm it doesn't check the filesystem - refoundPaths := finder.FindNamedAt("/tmp", "findme.txt") - assertSameResponse(t, refoundPaths, foundPaths) - assertSameStatCalls(t, filesystem.StatCalls, []string{}) - assertSameReadDirCalls(t, filesystem.ReadDirCalls, []string{}) - - finder.Shutdown() -} - -func TestChangingParamsOfSecondFind(t *testing.T) { - // setup filesystem - filesystem := newFs() - create(t, "/tmp/findme.txt", filesystem) - create(t, "/tmp/a/findme.txt", filesystem) - create(t, "/tmp/a/metoo.txt", filesystem) - - // set up the finder and run it once - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/tmp"}, - IncludeFiles: []string{"findme.txt", "metoo.txt"}, - }, - ) - foundPaths := finder.FindNamedAt("/tmp", "findme.txt") - assertSameResponse(t, foundPaths, []string{"/tmp/findme.txt", "/tmp/a/findme.txt"}) - - filesystem.ClearMetrics() - - // run the finder again and confirm it gets the right answer without asking the filesystem - refoundPaths := finder.FindNamedAt("/tmp", "metoo.txt") - assertSameResponse(t, refoundPaths, []string{"/tmp/a/metoo.txt"}) - assertSameStatCalls(t, filesystem.StatCalls, []string{}) - assertSameReadDirCalls(t, filesystem.ReadDirCalls, []string{}) - - finder.Shutdown() -} - -func TestSymlinkPointingToFile(t *testing.T) { - // setup filesystem - filesystem := newFs() - create(t, "/tmp/a/hi.txt", filesystem) - create(t, "/tmp/a/ignoreme.txt", filesystem) - link(t, "/tmp/hi.txt", "a/hi.txt", filesystem) - link(t, "/tmp/b/hi.txt", "../a/hi.txt", filesystem) - link(t, "/tmp/c/hi.txt", "/tmp/hi.txt", filesystem) - link(t, "/tmp/d/hi.txt", "../a/bye.txt", filesystem) - link(t, "/tmp/d/bye.txt", "../a/hi.txt", filesystem) - link(t, "/tmp/e/bye.txt", "../a/bye.txt", filesystem) - link(t, "/tmp/f/hi.txt", "somethingThatDoesntExist", filesystem) - - // set up the finder and run it once - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/tmp"}, - IncludeFiles: []string{"hi.txt"}, - }, - ) - foundPaths := finder.FindNamedAt("/tmp", "hi.txt") - // should search based on the name of the link rather than the destination or validity of the link - correctResponse := []string{ - "/tmp/a/hi.txt", - "/tmp/hi.txt", - "/tmp/b/hi.txt", - "/tmp/c/hi.txt", - "/tmp/d/hi.txt", - "/tmp/f/hi.txt", - } - assertSameResponse(t, foundPaths, correctResponse) - -} - -func TestSymlinkPointingToDirectory(t *testing.T) { - // setup filesystem - filesystem := newFs() - create(t, "/tmp/dir/hi.txt", filesystem) - create(t, "/tmp/dir/ignoreme.txt", filesystem) - - link(t, "/tmp/links/dir", "../dir", filesystem) - link(t, "/tmp/links/link", "../dir", filesystem) - link(t, "/tmp/links/broken", "nothingHere", filesystem) - link(t, "/tmp/links/recursive", "recursive", filesystem) - - // set up the finder and run it once - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/tmp"}, - IncludeFiles: []string{"hi.txt"}, - }, - ) - - foundPaths := finder.FindNamedAt("/tmp", "hi.txt") - - // should completely ignore symlinks that point to directories - correctResponse := []string{ - "/tmp/dir/hi.txt", - } - assertSameResponse(t, foundPaths, correctResponse) - -} - -// TestAddPruneFile confirms that adding a prune-file (into a directory for which we -// already had a cache) causes the directory to be ignored -func TestAddPruneFile(t *testing.T) { - // setup filesystem - filesystem := newFs() - create(t, "/tmp/out/hi.txt", filesystem) - create(t, "/tmp/out/a/hi.txt", filesystem) - create(t, "/tmp/hi.txt", filesystem) - - // do find - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/tmp"}, - PruneFiles: []string{".ignore-out-dir"}, - IncludeFiles: []string{"hi.txt"}, - }, - ) - - foundPaths := finder.FindNamedAt("/tmp", "hi.txt") - - // check result - assertSameResponse(t, foundPaths, - []string{"/tmp/hi.txt", - "/tmp/out/hi.txt", - "/tmp/out/a/hi.txt"}, - ) - finder.Shutdown() - - // modify filesystem - filesystem.Clock.Tick() - create(t, "/tmp/out/.ignore-out-dir", filesystem) - // run another find and check its result - finder2 := finderWithSameParams(t, finder) - foundPaths = finder2.FindNamedAt("/tmp", "hi.txt") - assertSameResponse(t, foundPaths, []string{"/tmp/hi.txt"}) - finder2.Shutdown() -} - -func TestUpdatingDbIffChanged(t *testing.T) { - // setup filesystem - filesystem := newFs() - create(t, "/tmp/a/hi.txt", filesystem) - create(t, "/tmp/b/bye.txt", filesystem) - - // run the first finder - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/tmp"}, - IncludeFiles: []string{"hi.txt"}, - }, - ) - foundPaths := finder.FindAll() - filesystem.Clock.Tick() - finder.Shutdown() - // check results - assertSameResponse(t, foundPaths, []string{"/tmp/a/hi.txt"}) - - // modify the filesystem - filesystem.Clock.Tick() - create(t, "/tmp/b/hi.txt", filesystem) - filesystem.Clock.Tick() - filesystem.ClearMetrics() - - // run the second finder - finder2 := finderWithSameParams(t, finder) - foundPaths = finder2.FindAll() - finder2.Shutdown() - // check results - assertSameResponse(t, foundPaths, []string{"/tmp/a/hi.txt", "/tmp/b/hi.txt"}) - assertSameReadDirCalls(t, filesystem.ReadDirCalls, []string{"/tmp/b"}) - expectedDbWriteTime := filesystem.Clock.Time() - actualDbWriteTime := modTime(t, finder2.DbPath, filesystem) - if actualDbWriteTime != expectedDbWriteTime { - t.Fatalf("Expected to write db at %v, actually wrote db at %v\n", - expectedDbWriteTime, actualDbWriteTime) - } - - // reset metrics - filesystem.ClearMetrics() - - // run the third finder - finder3 := finderWithSameParams(t, finder2) - foundPaths = finder3.FindAll() - - // check results - assertSameResponse(t, foundPaths, []string{"/tmp/a/hi.txt", "/tmp/b/hi.txt"}) - assertSameReadDirCalls(t, filesystem.ReadDirCalls, []string{}) - finder3.Shutdown() - actualDbWriteTime = modTime(t, finder3.DbPath, filesystem) - if actualDbWriteTime != expectedDbWriteTime { - t.Fatalf("Re-wrote db even when contents did not change") - } - -} - -func TestDirectoryNotPermitted(t *testing.T) { - // setup filesystem - filesystem := newFs() - create(t, "/tmp/hi.txt", filesystem) - create(t, "/tmp/a/hi.txt", filesystem) - create(t, "/tmp/a/a/hi.txt", filesystem) - create(t, "/tmp/b/hi.txt", filesystem) - - // run the first finder - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/tmp"}, - IncludeFiles: []string{"hi.txt"}, - }, - ) - foundPaths := finder.FindAll() - filesystem.Clock.Tick() - finder.Shutdown() - allPaths := []string{"/tmp/hi.txt", "/tmp/a/hi.txt", "/tmp/a/a/hi.txt", "/tmp/b/hi.txt"} - // check results - assertSameResponse(t, foundPaths, allPaths) - - // modify the filesystem - filesystem.Clock.Tick() - - setReadable(t, "/tmp/a", false, filesystem) - filesystem.Clock.Tick() - - // run the second finder - finder2 := finderWithSameParams(t, finder) - foundPaths = finder2.FindAll() - finder2.Shutdown() - // check results - assertSameResponse(t, foundPaths, []string{"/tmp/hi.txt", "/tmp/b/hi.txt"}) - - // modify the filesystem back - setReadable(t, "/tmp/a", true, filesystem) - - // run the third finder - finder3 := finderWithSameParams(t, finder2) - foundPaths = finder3.FindAll() - finder3.Shutdown() - // check results - assertSameResponse(t, foundPaths, allPaths) -} - -func TestFileNotPermitted(t *testing.T) { - // setup filesystem - filesystem := newFs() - create(t, "/tmp/hi.txt", filesystem) - setReadable(t, "/tmp/hi.txt", false, filesystem) - - // run the first finder - finder := newFinder( - t, - filesystem, - CacheParams{ - RootDirs: []string{"/tmp"}, - IncludeFiles: []string{"hi.txt"}, - }, - ) - foundPaths := finder.FindAll() - filesystem.Clock.Tick() - finder.Shutdown() - // check results - assertSameResponse(t, foundPaths, []string{"/tmp/hi.txt"}) -} |