aboutsummaryrefslogtreecommitdiffstats
path: root/golang/kati/pathutil_test.go
diff options
context:
space:
mode:
authorDan Willemsen <dwillemsen@google.com>2020-06-26 18:46:21 -0700
committerDan Willemsen <dwillemsen@google.com>2020-06-26 18:52:06 -0700
commit979e7ae6e417ae4ee45e835104b66191ae16a14c (patch)
tree6b5075e832cbdf2a7996a25a26659363527b6e4c /golang/kati/pathutil_test.go
parent003cf51e9b6da48063c90cf4c6710fde103c9c4a (diff)
downloadplatform_build_kati-979e7ae6e417ae4ee45e835104b66191ae16a14c.tar.gz
platform_build_kati-979e7ae6e417ae4ee45e835104b66191ae16a14c.tar.bz2
platform_build_kati-979e7ae6e417ae4ee45e835104b66191ae16a14c.zip
Refactor source tree into directories
Now instead of almost every file in the top level, move the old go code into its own directory 'golang', and the C++ code into it's own 'src' Also removes a few obsolete scripts that were used to work on Android before Android fully switched to Kati.
Diffstat (limited to 'golang/kati/pathutil_test.go')
-rw-r--r--golang/kati/pathutil_test.go800
1 files changed, 800 insertions, 0 deletions
diff --git a/golang/kati/pathutil_test.go b/golang/kati/pathutil_test.go
new file mode 100644
index 0000000..33b7e32
--- /dev/null
+++ b/golang/kati/pathutil_test.go
@@ -0,0 +1,800 @@
+// Copyright 2015 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 kati
+
+import (
+ "os"
+ "path/filepath"
+ "reflect"
+ "strings"
+ "testing"
+)
+
+type mockfs struct {
+ id fileid
+ ofscache *fsCacheT
+}
+
+func newFS() *mockfs {
+ fs := &mockfs{
+ ofscache: fsCache,
+ }
+ fsCache = &fsCacheT{
+ ids: make(map[string]fileid),
+ dirents: make(map[fileid][]dirent),
+ }
+ fsCache.ids["."] = fs.dir(".").id
+ return fs
+}
+
+func (m *mockfs) dump(t *testing.T) {
+ t.Log("fs ids:")
+ for name, id := range fsCache.ids {
+ t.Logf(" %q=%v", name, id)
+ }
+ t.Log("fs dirents:")
+ for id, ents := range fsCache.dirents {
+ t.Logf(" %v:", id)
+ for _, ent := range ents {
+ t.Logf(" %#v", ent)
+ }
+ }
+}
+
+func (m *mockfs) close() {
+ fsCache = m.ofscache
+}
+
+func (m *mockfs) dirent(name string, mode os.FileMode) dirent {
+ id := m.id
+ m.id.ino++
+ return dirent{id: id, name: name, mode: mode, lmode: mode}
+}
+
+func (m *mockfs) addent(name string, ent dirent) {
+ dir, name := filepath.Split(name)
+ dir = strings.TrimSuffix(dir, string(filepath.Separator))
+ if dir == "" {
+ dir = "."
+ }
+ di, ok := fsCache.ids[dir]
+ if !ok {
+ if dir == "." {
+ panic(". not found:" + name)
+ }
+ de := m.add(m.dir, dir)
+ fsCache.ids[dir] = de.id
+ di = de.id
+ }
+ for _, e := range fsCache.dirents[di] {
+ if e.name == ent.name {
+ return
+ }
+ }
+ fsCache.dirents[di] = append(fsCache.dirents[di], ent)
+}
+
+func (m *mockfs) add(t func(string) dirent, name string) dirent {
+ ent := t(filepath.Base(name))
+ m.addent(name, ent)
+ return ent
+}
+
+func (m *mockfs) symlink(name string, ent dirent) {
+ lent := ent
+ lent.lmode = os.ModeSymlink
+ lent.name = filepath.Base(name)
+ m.addent(name, lent)
+}
+
+func (m *mockfs) dirref(name string) dirent {
+ id := fsCache.ids[name]
+ return dirent{id: id, name: filepath.Base(name), mode: os.ModeDir, lmode: os.ModeDir}
+}
+
+func (m *mockfs) notfound() dirent { return dirent{id: invalidFileid} }
+func (m *mockfs) dir(name string) dirent { return m.dirent(name, os.ModeDir) }
+func (m *mockfs) file(name string) dirent { return m.dirent(name, os.FileMode(0644)) }
+
+func TestFilepathClean(t *testing.T) {
+ fs := newFS()
+ defer fs.close()
+ di := fs.add(fs.dir, "dir")
+ fs.symlink("link", di)
+
+ fs.dump(t)
+
+ for _, tc := range []struct {
+ path string
+ want string
+ }{
+ {path: "foo", want: "foo"},
+ {path: ".", want: "."},
+ {path: "./", want: "."},
+ {path: ".///", want: "."},
+ {path: "", want: "."},
+ {path: "foo/bar", want: "foo/bar"},
+ {path: "./foo", want: "foo"},
+ {path: "foo///", want: "foo"},
+ {path: "foo//bar", want: "foo/bar"},
+ {path: "foo/../bar", want: "foo/../bar"}, // foo doesn't exist
+ {path: "dir/../bar", want: "bar"}, // dir is real dir
+ {path: "link/../bar", want: "link/../bar"}, // link is symlink
+ {path: "foo/./bar", want: "foo/bar"},
+ {path: "/foo/bar", want: "/foo/bar"},
+ } {
+ if got, want := filepathClean(tc.path), tc.want; got != want {
+ t.Errorf("filepathClean(%q)=%q; want=%q", tc.path, got, want)
+ }
+ }
+}
+
+func TestParseFindCommand(t *testing.T) {
+ fs := newFS()
+ defer fs.close()
+ fs.add(fs.dir, "testdir")
+
+ maxdepth := 1<<31 - 1
+ for _, tc := range []struct {
+ cmd string
+ want findCommand
+ }{
+ {
+ cmd: "find testdir",
+ want: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpPrint{}},
+ depth: maxdepth,
+ },
+ },
+ {
+ cmd: "find .",
+ want: findCommand{
+ finddirs: []string{"."},
+ ops: []findOp{findOpPrint{}},
+ depth: maxdepth,
+ },
+ },
+ {
+ cmd: "find ",
+ want: findCommand{
+ finddirs: []string{"."},
+ ops: []findOp{findOpPrint{}},
+ depth: maxdepth,
+ },
+ },
+ {
+ cmd: "find testdir/../testdir",
+ want: findCommand{
+ finddirs: []string{"testdir/../testdir"},
+ ops: []findOp{findOpPrint{}},
+ depth: maxdepth,
+ },
+ },
+ {
+ cmd: "find testdir -print",
+ want: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpPrint{}},
+ depth: maxdepth,
+ },
+ },
+ {
+ cmd: "find testdir -name foo",
+ want: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpName("foo"), findOpPrint{}},
+ depth: maxdepth,
+ },
+ },
+ {
+ cmd: `find testdir -name "file1"`,
+ want: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpName("file1"), findOpPrint{}},
+ depth: maxdepth,
+ },
+ },
+ {
+ cmd: `find testdir -name "*1"`,
+ want: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpName("*1"), findOpPrint{}},
+ depth: maxdepth,
+ },
+ },
+ {
+ cmd: `find testdir -name "*1" -and -name "file*"`,
+ want: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpAnd{findOpName("*1"), findOpName("file*")}, findOpPrint{}},
+ depth: maxdepth,
+ },
+ },
+ {
+ cmd: `find testdir -name "*1" -or -name "file*"`,
+ want: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpOr{findOpName("*1"), findOpName("file*")}, findOpPrint{}},
+ depth: maxdepth,
+ },
+ },
+ {
+ cmd: `find testdir -name "*1" -or -type f`,
+ want: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpOr{findOpName("*1"), findOpRegular{}}, findOpPrint{}},
+ depth: maxdepth,
+ },
+ },
+ {
+ cmd: `find testdir -name "*1" -or -not -type f`,
+ want: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpOr{findOpName("*1"), findOpNot{findOpRegular{}}}, findOpPrint{}},
+ depth: maxdepth,
+ },
+ },
+ {
+ cmd: `find testdir -name "*1" -or \! -type f`,
+ want: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpOr{findOpName("*1"), findOpNot{findOpRegular{}}}, findOpPrint{}},
+ depth: maxdepth,
+ },
+ },
+ {
+ cmd: `find testdir -name "*1" -or -type d`,
+ want: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpOr{findOpName("*1"), findOpType{mode: os.ModeDir}}, findOpPrint{}},
+ depth: maxdepth,
+ },
+ },
+ {
+ cmd: `find testdir -name "*1" -or -type l`,
+ want: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpOr{findOpName("*1"), findOpType{mode: os.ModeSymlink}}, findOpPrint{}},
+ depth: maxdepth,
+ },
+ },
+ {
+ cmd: `find testdir -name "*1" -a -type l -o -name "dir*"`,
+ want: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpOr{findOpAnd([]findOp{findOpName("*1"), findOpType{mode: os.ModeSymlink}}), findOpName("dir*")}, findOpPrint{}},
+ depth: maxdepth,
+ },
+ },
+ {
+ cmd: `find testdir \( -name "dir*" -o -name "*1" \) -a -type f`,
+ want: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpAnd([]findOp{findOpOr{findOpName("dir*"), findOpName("*1")}, findOpRegular{}}), findOpPrint{}},
+ depth: maxdepth,
+ },
+ },
+ {
+ cmd: `cd testdir && find`,
+ want: findCommand{
+ chdir: "testdir",
+ finddirs: []string{"."},
+ ops: []findOp{findOpPrint{}},
+ depth: maxdepth,
+ },
+ },
+ {
+ cmd: `test -d testdir && find testdir`,
+ want: findCommand{
+ testdir: "testdir",
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpPrint{}},
+ depth: maxdepth,
+ },
+ },
+ {
+ cmd: `if [ -d testdir ] ; then find testdir ; fi`,
+ want: findCommand{
+ testdir: "testdir",
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpPrint{}},
+ depth: maxdepth,
+ },
+ },
+ {
+ cmd: `if [ -d testdir ]; then find testdir; fi`,
+ want: findCommand{
+ testdir: "testdir",
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpPrint{}},
+ depth: maxdepth,
+ },
+ },
+ {
+ cmd: `if [ -d testdir ]; then cd testdir && find .; fi`,
+ want: findCommand{
+ chdir: "testdir",
+ testdir: "testdir",
+ finddirs: []string{"."},
+ ops: []findOp{findOpPrint{}},
+ depth: maxdepth,
+ },
+ },
+ {
+ cmd: `find testdir -name dir2 -prune -o -name file1`,
+ want: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpOr{findOpAnd([]findOp{findOpName("dir2"), findOpPrune{}}), findOpName("file1")}, findOpPrint{}},
+ depth: maxdepth,
+ },
+ },
+ {
+ cmd: `find testdir testdir`,
+ want: findCommand{
+ finddirs: []string{"testdir", "testdir"},
+ ops: []findOp{findOpPrint{}},
+ depth: maxdepth,
+ },
+ },
+ {
+ cmd: `find -L testdir -type f`,
+ want: findCommand{
+ finddirs: []string{"testdir"},
+ followSymlinks: true,
+ ops: []findOp{findOpRegular{followSymlinks: true}, findOpPrint{}},
+ depth: maxdepth,
+ },
+ },
+ {
+ cmd: `cd testdir; find -L . -type f`,
+ want: findCommand{
+ chdir: "testdir",
+ finddirs: []string{"."},
+ followSymlinks: true,
+ ops: []findOp{findOpRegular{followSymlinks: true}, findOpPrint{}},
+ depth: maxdepth,
+ },
+ },
+ {
+ cmd: `find testdir -maxdepth 1`,
+ want: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpPrint{}},
+ depth: 1,
+ },
+ },
+ {
+ cmd: `find testdir -maxdepth 0`,
+ want: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpPrint{}},
+ depth: 0,
+ },
+ },
+ } {
+ fc, err := parseFindCommand(tc.cmd)
+ if err != nil {
+ t.Errorf("parseFindCommand(%q)=_, %v; want=_, <nil>", tc.cmd, err)
+ continue
+ }
+ if got, want := fc, tc.want; !reflect.DeepEqual(got, want) {
+ t.Errorf("parseFindCommand(%q)=%#v\n want=%#v\n", tc.cmd, got, want)
+ }
+ }
+
+}
+
+func TestParseFindCommandFail(t *testing.T) {
+ for _, cmd := range []string{
+ `find testdir -maxdepth hoge`,
+ `find testdir -maxdepth 1hoge`,
+ `find testdir -maxdepth -1`,
+ } {
+ _, err := parseFindCommand(cmd)
+ if err == nil {
+ t.Errorf("parseFindCommand(%q)=_, <nil>; want=_, err", cmd)
+ }
+ }
+}
+
+func TestFind(t *testing.T) {
+ fs := newFS()
+ defer fs.close()
+ fs.add(fs.file, "Makefile")
+ fs.add(fs.file, "testdir/file1")
+ fs.add(fs.file, "testdir/file2")
+ file1 := fs.add(fs.file, "testdir/dir1/file1")
+ dir1 := fs.dirref("testdir/dir1")
+ fs.add(fs.file, "testdir/dir1/file2")
+ fs.add(fs.file, "testdir/dir2/file1")
+ fs.add(fs.file, "testdir/dir2/file2")
+ fs.symlink("testdir/dir2/link1", file1)
+ fs.symlink("testdir/dir2/link2", dir1)
+ fs.symlink("testdir/dir2/link3", fs.notfound())
+
+ fs.dump(t)
+
+ maxdepth := 1<<31 - 1
+ for _, tc := range []struct {
+ fc findCommand
+ want string
+ }{
+ {
+ fc: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: `testdir testdir/file1 testdir/file2 testdir/dir1 testdir/dir1/file1 testdir/dir1/file2 testdir/dir2 testdir/dir2/file1 testdir/dir2/file2 testdir/dir2/link1 testdir/dir2/link2 testdir/dir2/link3`,
+ },
+ {
+ fc: findCommand{
+ finddirs: []string{"."},
+ ops: []findOp{findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: `. ./Makefile ./testdir ./testdir/file1 ./testdir/file2 ./testdir/dir1 ./testdir/dir1/file1 ./testdir/dir1/file2 ./testdir/dir2 ./testdir/dir2/file1 ./testdir/dir2/file2 ./testdir/dir2/link1 ./testdir/dir2/link2 ./testdir/dir2/link3`,
+ },
+ {
+ fc: findCommand{
+ finddirs: []string{"./"},
+ ops: []findOp{findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: `./ ./Makefile ./testdir ./testdir/file1 ./testdir/file2 ./testdir/dir1 ./testdir/dir1/file1 ./testdir/dir1/file2 ./testdir/dir2 ./testdir/dir2/file1 ./testdir/dir2/file2 ./testdir/dir2/link1 ./testdir/dir2/link2 ./testdir/dir2/link3`,
+ },
+ {
+ fc: findCommand{
+ finddirs: []string{".///"},
+ ops: []findOp{findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: `./// .///Makefile .///testdir .///testdir/file1 .///testdir/file2 .///testdir/dir1 .///testdir/dir1/file1 .///testdir/dir1/file2 .///testdir/dir2 .///testdir/dir2/file1 .///testdir/dir2/file2 .///testdir/dir2/link1 .///testdir/dir2/link2 .///testdir/dir2/link3`,
+ },
+ {
+ fc: findCommand{
+ finddirs: []string{"./."},
+ ops: []findOp{findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: `./. ././Makefile ././testdir ././testdir/file1 ././testdir/file2 ././testdir/dir1 ././testdir/dir1/file1 ././testdir/dir1/file2 ././testdir/dir2 ././testdir/dir2/file1 ././testdir/dir2/file2 ././testdir/dir2/link1 ././testdir/dir2/link2 ././testdir/dir2/link3`,
+ },
+ {
+ fc: findCommand{
+ finddirs: []string{"././"},
+ ops: []findOp{findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: `././ ././Makefile ././testdir ././testdir/file1 ././testdir/file2 ././testdir/dir1 ././testdir/dir1/file1 ././testdir/dir1/file2 ././testdir/dir2 ././testdir/dir2/file1 ././testdir/dir2/file2 ././testdir/dir2/link1 ././testdir/dir2/link2 ././testdir/dir2/link3`,
+ },
+ {
+ fc: findCommand{
+ finddirs: []string{"testdir/../testdir"},
+ ops: []findOp{findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: `testdir/../testdir testdir/../testdir/file1 testdir/../testdir/file2 testdir/../testdir/dir1 testdir/../testdir/dir1/file1 testdir/../testdir/dir1/file2 testdir/../testdir/dir2 testdir/../testdir/dir2/file1 testdir/../testdir/dir2/file2 testdir/../testdir/dir2/link1 testdir/../testdir/dir2/link2 testdir/../testdir/dir2/link3`,
+ },
+ {
+ fc: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpName("foo"), findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: ``,
+ },
+ {
+ fc: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpName("file1"), findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: `testdir/file1 testdir/dir1/file1 testdir/dir2/file1`,
+ },
+ {
+ fc: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpAnd{findOpName("*1"), findOpName("file*")}, findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: `testdir/file1 testdir/dir1/file1 testdir/dir2/file1`,
+ },
+ {
+ fc: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpOr{findOpName("*1"), findOpName("file*")}, findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: `testdir/file1 testdir/file2 testdir/dir1 testdir/dir1/file1 testdir/dir1/file2 testdir/dir2/file1 testdir/dir2/file2 testdir/dir2/link1`,
+ },
+ {
+ fc: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpOr{findOpName("*1"), findOpRegular{}}, findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: `testdir/file1 testdir/file2 testdir/dir1 testdir/dir1/file1 testdir/dir1/file2 testdir/dir2/file1 testdir/dir2/file2 testdir/dir2/link1`,
+ },
+ {
+ fc: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpOr{findOpName("*1"), findOpNot{findOpRegular{}}}, findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: `testdir testdir/file1 testdir/dir1 testdir/dir1/file1 testdir/dir2 testdir/dir2/file1 testdir/dir2/link1 testdir/dir2/link2 testdir/dir2/link3`,
+ },
+ {
+ fc: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpOr{findOpName("*1"), findOpType{mode: os.ModeDir}}, findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: `testdir testdir/file1 testdir/dir1 testdir/dir1/file1 testdir/dir2 testdir/dir2/file1 testdir/dir2/link1`,
+ },
+ {
+ fc: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpOr{findOpName("*1"), findOpType{mode: os.ModeSymlink}}, findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: `testdir/file1 testdir/dir1 testdir/dir1/file1 testdir/dir2/file1 testdir/dir2/link1 testdir/dir2/link2 testdir/dir2/link3`,
+ },
+ {
+ fc: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpOr{findOpAnd([]findOp{findOpName("*1"), findOpType{mode: os.ModeSymlink}}), findOpName("dir*")}, findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: `testdir/dir1 testdir/dir2 testdir/dir2/link1`,
+ },
+ {
+ fc: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpOr{findOpAnd([]findOp{findOpName("*1"), findOpType{mode: os.ModeSymlink}}), findOpName("dir*")}, findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: `testdir/dir1 testdir/dir2 testdir/dir2/link1`,
+ },
+ {
+ fc: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpAnd([]findOp{findOpOr{findOpName("dir*"), findOpName("*1")}, findOpRegular{}}), findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: `testdir/file1 testdir/dir1/file1 testdir/dir2/file1`,
+ },
+ {
+ fc: findCommand{
+ chdir: "testdir",
+ finddirs: []string{"."},
+ ops: []findOp{findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: `. ./file1 ./file2 ./dir1 ./dir1/file1 ./dir1/file2 ./dir2 ./dir2/file1 ./dir2/file2 ./dir2/link1 ./dir2/link2 ./dir2/link3`,
+ },
+ {
+ fc: findCommand{
+ chdir: "testdir",
+ finddirs: []string{"../testdir"},
+ ops: []findOp{findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: `../testdir ../testdir/file1 ../testdir/file2 ../testdir/dir1 ../testdir/dir1/file1 ../testdir/dir1/file2 ../testdir/dir2 ../testdir/dir2/file1 ../testdir/dir2/file2 ../testdir/dir2/link1 ../testdir/dir2/link2 ../testdir/dir2/link3`,
+ },
+ {
+ fc: findCommand{
+ testdir: "testdir",
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: `testdir testdir/file1 testdir/file2 testdir/dir1 testdir/dir1/file1 testdir/dir1/file2 testdir/dir2 testdir/dir2/file1 testdir/dir2/file2 testdir/dir2/link1 testdir/dir2/link2 testdir/dir2/link3`,
+ },
+ {
+ fc: findCommand{
+ chdir: "testdir",
+ testdir: "testdir",
+ finddirs: []string{"."},
+ ops: []findOp{findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: `. ./file1 ./file2 ./dir1 ./dir1/file1 ./dir1/file2 ./dir2 ./dir2/file1 ./dir2/file2 ./dir2/link1 ./dir2/link2 ./dir2/link3`,
+ },
+ {
+ fc: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpOr{findOpAnd([]findOp{findOpName("dir2"), findOpPrune{}}), findOpName("file1")}, findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: `testdir/file1 testdir/dir1/file1 testdir/dir2`,
+ },
+ {
+ fc: findCommand{
+ finddirs: []string{"testdir", "testdir"},
+ ops: []findOp{findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: `testdir testdir/file1 testdir/file2 testdir/dir1 testdir/dir1/file1 testdir/dir1/file2 testdir/dir2 testdir/dir2/file1 testdir/dir2/file2 testdir/dir2/link1 testdir/dir2/link2 testdir/dir2/link3 testdir testdir/file1 testdir/file2 testdir/dir1 testdir/dir1/file1 testdir/dir1/file2 testdir/dir2 testdir/dir2/file1 testdir/dir2/file2 testdir/dir2/link1 testdir/dir2/link2 testdir/dir2/link3`,
+ },
+ // symlink
+ {
+ fc: findCommand{
+ finddirs: []string{"testdir"},
+ followSymlinks: true,
+ ops: []findOp{findOpRegular{followSymlinks: true}, findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: `testdir/file1 testdir/file2 testdir/dir1/file1 testdir/dir1/file2 testdir/dir2/file1 testdir/dir2/file2 testdir/dir2/link1 testdir/dir2/link2/file1 testdir/dir2/link2/file2`,
+ },
+ {
+ fc: findCommand{
+ finddirs: []string{"testdir"},
+ followSymlinks: true,
+ ops: []findOp{findOpType{mode: os.ModeDir, followSymlinks: true}, findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: `testdir testdir/dir1 testdir/dir2 testdir/dir2/link2`,
+ },
+ {
+ fc: findCommand{
+ finddirs: []string{"testdir"},
+ followSymlinks: true,
+ ops: []findOp{findOpType{mode: os.ModeSymlink, followSymlinks: true}, findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: `testdir/dir2/link3`,
+ },
+ {
+ fc: findCommand{
+ chdir: "testdir",
+ finddirs: []string{"."},
+ followSymlinks: true,
+ ops: []findOp{findOpRegular{followSymlinks: true}, findOpPrint{}},
+ depth: maxdepth,
+ },
+ want: `./file1 ./file2 ./dir1/file1 ./dir1/file2 ./dir2/file1 ./dir2/file2 ./dir2/link1 ./dir2/link2/file1 ./dir2/link2/file2`,
+ },
+ // maxdepth
+ {
+ fc: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpPrint{}},
+ depth: 1,
+ },
+ want: `testdir testdir/file1 testdir/file2 testdir/dir1 testdir/dir2`,
+ },
+ {
+ fc: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpPrint{}},
+ depth: 2,
+ },
+ want: `testdir testdir/file1 testdir/file2 testdir/dir1 testdir/dir1/file1 testdir/dir1/file2 testdir/dir2 testdir/dir2/file1 testdir/dir2/file2 testdir/dir2/link1 testdir/dir2/link2 testdir/dir2/link3`,
+ },
+ {
+ fc: findCommand{
+ finddirs: []string{"testdir"},
+ ops: []findOp{findOpPrint{}},
+ depth: 0,
+ },
+ want: `testdir`,
+ },
+ } {
+ var wb wordBuffer
+ tc.fc.run(&wb)
+ if got, want := wb.buf.String(), tc.want; got != want {
+ t.Errorf("%#v\n got %q\n want %q", tc.fc, got, want)
+ }
+ }
+}
+
+func TestParseFindleavesCommand(t *testing.T) {
+ for _, tc := range []struct {
+ cmd string
+ want findleavesCommand
+ }{
+ {
+ cmd: `build/tools/findleaves.py --prune=out --prune=.repo --prune=.git . CleanSpec.mk`,
+ want: findleavesCommand{
+ name: "CleanSpec.mk",
+ dirs: []string{"."},
+ prunes: []string{"out", ".repo", ".git"},
+ mindepth: -1,
+ },
+ },
+ {
+ cmd: `build/tools/findleaves.py --prune=out --prune=.repo --prune=.git --mindepth=2 art bionic Android.mk`,
+ want: findleavesCommand{
+ name: "Android.mk",
+ dirs: []string{"art", "bionic"},
+ prunes: []string{"out", ".repo", ".git"},
+ mindepth: 2,
+ },
+ },
+ } {
+ fc, err := parseFindleavesCommand(tc.cmd)
+ if err != nil {
+ t.Errorf("parseFindleavesCommand(%q)=_, %v; want=_, <nil", tc.cmd, err)
+ continue
+ }
+ if got, want := fc, tc.want; !reflect.DeepEqual(got, want) {
+ t.Errorf("parseFindleavesCommand(%q)=%#v\n want=%#v\n", tc.cmd, got, want)
+ }
+ }
+}
+
+func TestFindleaves(t *testing.T) {
+ fs := newFS()
+ defer fs.close()
+
+ fs.add(fs.file, "art/Android.mk")
+ fs.add(fs.file, "art/compiler/Android.mk")
+ fs.add(fs.file, "art/CleanSpec.mk")
+ fs.add(fs.file, "bionic/Android.mk")
+ fs.add(fs.file, "bionic/CleanSpec.mk")
+ fs.add(fs.file, "bootable/recovery/Android.mk")
+ fs.add(fs.file, "bootable/recovery/CleanSpec.mk")
+ fs.add(fs.file, "frameworks/base/Android.mk")
+ fs.add(fs.file, "frameworks/base/CleanSpec.mk")
+ fs.add(fs.file, "frameworks/base/cmds/am/Android.mk")
+ fs.add(fs.file, "frameworks/base/cmds/pm/Android.mk")
+ fs.add(fs.file, "frameworks/base/location/Android.mk")
+ fs.add(fs.file, "frameworks/base/packages/WAPPushManager/CleanSpec.mk")
+ fs.add(fs.file, "out/outputfile")
+ fs.add(fs.file, "art/.git/index")
+ fs.add(fs.file, ".repo/manifests")
+
+ fs.dump(t)
+
+ for _, tc := range []struct {
+ fc findleavesCommand
+ want string
+ }{
+ {
+ fc: findleavesCommand{
+ name: "CleanSpec.mk",
+ dirs: []string{"."},
+ prunes: []string{"out", ".repo", ".git"},
+ mindepth: -1,
+ },
+ want: `./art/CleanSpec.mk ./bionic/CleanSpec.mk ./bootable/recovery/CleanSpec.mk ./frameworks/base/CleanSpec.mk`,
+ },
+ {
+ fc: findleavesCommand{
+ name: "Android.mk",
+ dirs: []string{"art", "bionic", "frameworks/base"},
+ prunes: []string{"out", ".repo", ".git"},
+ mindepth: 2,
+ },
+ want: `art/compiler/Android.mk frameworks/base/cmds/am/Android.mk frameworks/base/cmds/pm/Android.mk frameworks/base/location/Android.mk`,
+ },
+ {
+ fc: findleavesCommand{
+ name: "Android.mk",
+ dirs: []string{"art", "bionic", "frameworks/base"},
+ prunes: []string{"out", ".repo", ".git"},
+ mindepth: 3,
+ },
+ want: `frameworks/base/cmds/am/Android.mk frameworks/base/cmds/pm/Android.mk`,
+ },
+ } {
+ var wb wordBuffer
+ tc.fc.run(&wb)
+ if got, want := wb.buf.String(), tc.want; got != want {
+ t.Errorf("%#v\n got %q\n want %q", tc.fc, got, want)
+ }
+ }
+}