tests: filter leaked fds by prefix

When running

  $ go test ./tests/matrix/

in isolation, it failed like this:

  fd leak? before, after:
  [0r=/dev/null 3w=/dev/null 5r=/proc/8078/fd (hidden:4)]
  [0r=/dev/null 3w=/dev/null 5w=/tmp/go-build366655199/b001/testlog.txt 7r=/proc/8078/fd (hidden:4)]

Filter by prefix to get rid of this spurious test failure.
This commit is contained in:
Jakob Unterwurzacher 2019-10-06 19:04:16 +02:00
parent d361f6e35b
commit 1fb18f4a9e
3 changed files with 18 additions and 12 deletions

View File

@ -22,9 +22,9 @@ var testPw = []byte("test")
func TestMain(m *testing.M) {
test_helpers.ResetTmpDir(false)
before := test_helpers.ListFds(0)
before := test_helpers.ListFds(0, "")
r := m.Run()
after := test_helpers.ListFds(0)
after := test_helpers.ListFds(0, "")
if len(before) != len(after) {
fmt.Printf("fd leak in test process? before, after:\n%v\n%v\n", before, after)
os.Exit(1)

View File

@ -77,11 +77,13 @@ func TestMain(m *testing.M) {
opts = append(opts, fmt.Sprintf("-raw64=%v", testcase.raw64))
opts = append(opts, testcase.extraArgs...)
test_helpers.MountOrExit(test_helpers.DefaultCipherDir, test_helpers.DefaultPlainDir, opts...)
before := test_helpers.ListFds(0)
before := test_helpers.ListFds(0, test_helpers.TmpDir)
r := m.Run()
// Catch fd leaks in the tests. NOTE: this does NOT catch leaks in
// the gocryptfs FUSE process, but only in the tests that access it!
after := test_helpers.ListFds(0)
// All fds that point outside TmpDir are not interesting (the Go test
// infrastucture creates temporary log files we don't care about).
after := test_helpers.ListFds(0, test_helpers.TmpDir)
if len(before) != len(after) {
fmt.Printf("fd leak in test process? before, after:\n%v\n%v\n", before, after)
os.Exit(1)

View File

@ -91,7 +91,7 @@ func Mount(c string, p string, showOutput bool, extraArgs ...string) error {
}
// Save PID and open FDs
MountInfo[p] = mountInfo{pid, ListFds(pid)}
MountInfo[p] = mountInfo{pid, ListFds(pid, "")}
return nil
}
@ -160,13 +160,13 @@ func UnmountErr(dir string) (err error) {
// when testing "-ctlsock" is as well. Wait a little and
// hope that all close commands get through to the gocryptfs
// process.
fdsNow = ListFds(pid)
fdsNow = ListFds(pid, "")
if len(fdsNow) <= len(fds)+maxCacheFds {
break
}
fmt.Printf("UnmountErr: fdsOld=%d fdsNow=%d, retrying\n", len(fds), len(fdsNow))
time.Sleep(10 * time.Millisecond)
fdsNow = ListFds(pid)
fdsNow = ListFds(pid, "")
}
}
cmd := exec.Command(UnmountScript, "-u", dir)
@ -187,8 +187,8 @@ func UnmountErr(dir string) (err error) {
}
// ListFds lists the open file descriptors for process "pid". Pass pid=0 for
// ourselves.
func ListFds(pid int) []string {
// ourselves. Pass a prefix to ignore all paths that do not start with "prefix".
func ListFds(pid int, prefix string) []string {
// We need /proc to get the list of fds for other processes. Only exists
// on Linux.
if runtime.GOOS != "linux" && pid > 0 {
@ -211,7 +211,7 @@ func ListFds(pid int) []string {
log.Panic(err)
}
var out []string
hidden := 0
var filtered []string
for _, n := range names {
fdPath := dir + "/" + n
fi, err := os.Lstat(fdPath)
@ -235,11 +235,15 @@ func ListFds(pid int) []string {
// creates spurious test failures. Ignore all pipes.
// Also get rid of the "eventpoll" fd that is always there and not
// interesting.
hidden++
filtered = append(filtered, target)
continue
}
if prefix != "" && !strings.HasPrefix(target, prefix) {
filtered = append(filtered, target)
continue
}
out = append(out, n+"="+target)
}
out = append(out, fmt.Sprintf("(hidden:%d)", hidden))
out = append(out, fmt.Sprintf("(filtered: %s)", strings.Join(filtered, ", ")))
return out
}