summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorJakob Unterwurzacher2019-01-01 22:01:49 +0100
committerJakob Unterwurzacher2019-01-01 22:01:49 +0100
commit10de105c13e4ef512fe83b8c1074fc453f3e70ff (patch)
tree437c4a1aac2c2050d87ca0c9fbf2d400dc6eadad /tests
parentcd0ec342b9692c71c50c77caa7b9cfde27426e4d (diff)
tests: detect fd leaks on unmount
For now, this only prints a message but does not fail the tests.
Diffstat (limited to 'tests')
-rw-r--r--tests/defaults/ctlsock_test.go7
-rw-r--r--tests/test_helpers/helpers.go33
2 files changed, 35 insertions, 5 deletions
diff --git a/tests/defaults/ctlsock_test.go b/tests/defaults/ctlsock_test.go
index b987bf6..212ded4 100644
--- a/tests/defaults/ctlsock_test.go
+++ b/tests/defaults/ctlsock_test.go
@@ -4,6 +4,7 @@ import (
"os"
"syscall"
"testing"
+ "time"
"github.com/rfjakob/gocryptfs/internal/ctlsock"
"github.com/rfjakob/gocryptfs/tests/test_helpers"
@@ -37,6 +38,9 @@ func TestCtlSock(t *testing.T) {
t.Errorf("We should get a warning about non-canonical paths here")
}
}
+ // Give the running gocryptfs process a little bit of time to close lingering
+ // sockets. Avoid triggering the FD leak detector.
+ time.Sleep(1 * time.Millisecond)
}
func TestCtlSockDecrypt(t *testing.T) {
@@ -87,6 +91,9 @@ func TestCtlSockDecrypt(t *testing.T) {
t.Errorf("want=%q got=%q", p, response.Result)
}
}
+ // Give the running gocryptfs process a little bit of time to close lingering
+ // sockets. Avoid triggering the FD leak detector.
+ time.Sleep(1 * time.Millisecond)
}
func TestCtlSockDecryptCrash(t *testing.T) {
diff --git a/tests/test_helpers/helpers.go b/tests/test_helpers/helpers.go
index 22f47b2..1982b96 100644
--- a/tests/test_helpers/helpers.go
+++ b/tests/test_helpers/helpers.go
@@ -46,8 +46,15 @@ var DefaultPlainDir string
// DefaultCipherDir is TmpDir + "/default-cipher"
var DefaultCipherDir string
-// PID of the running gocryptfs process. Set by Mount().
-var MountPID int
+type mountInfo struct {
+ // PID of the running gocryptfs process. Set by Mount().
+ pid int
+ // List of open FDs of the running gocrypts process. Set by Mount().
+ fds []string
+}
+
+// Indexed by mountpoint
+var MountInfo map[string]mountInfo
// SwitchTMPDIR changes TMPDIR and hence the directory the test are performed in.
// This is used when you want to perform tests on a special filesystem. The
@@ -63,6 +70,7 @@ func init() {
func doInit() {
X255 = string(bytes.Repeat([]byte("X"), 255))
+ MountInfo = make(map[string]mountInfo)
testParentDir := os.TempDir() + "/gocryptfs-test-parent"
os.MkdirAll(testParentDir, 0700)
@@ -205,7 +213,7 @@ func Mount(c string, p string, showOutput bool, extraArgs ...string) error {
if err != nil {
return err
}
- MountPID = cmd.Process.Pid
+ pid := cmd.Process.Pid
// Wait for exit or usr1
go func() {
@@ -215,11 +223,13 @@ func Mount(c string, p string, showOutput bool, extraArgs ...string) error {
case err := <-chanExit:
return err
case <-chanUsr1:
- return nil
+ // noop
case <-time.After(1 * time.Second):
- log.Panicf("Timeout waiting for process %d", MountPID)
+ log.Panicf("Timeout waiting for process %d", pid)
}
+ // Save PID and open FDs
+ MountInfo[p] = mountInfo{pid, ListFds(pid)}
return nil
}
@@ -256,6 +266,13 @@ func UnmountPanic(dir string) {
// UnmountErr tries to unmount "dir", retrying 10 times, and returns the
// resulting error.
func UnmountErr(dir string) (err error) {
+ var fdsNow []string
+ pid := MountInfo[dir].pid
+ fds := MountInfo[dir].fds
+ if pid <= 0 {
+ fmt.Printf("UnmountErr: %q was not found in MountInfo, cannot check for FD leaks\n", dir)
+ }
+
max := 10
// When a new filesystem is mounted, Gnome tries to read files like
// .xdg-volume-info, autorun.inf, .Trash.
@@ -263,11 +280,17 @@ func UnmountErr(dir string) (err error) {
// "Device or resource busy", causing spurious test failures.
// Retry a few times to hide that problem.
for i := 1; i <= max; i++ {
+ if pid > 0 {
+ fdsNow = ListFds(pid)
+ }
cmd := exec.Command(UnmountScript, "-u", dir)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err = cmd.Run()
if err == nil {
+ if pid > 0 && len(fdsNow) > len(fds) {
+ fmt.Printf("FD leak? Details:\nold=%v \nnew=%v\n", fds, fdsNow)
+ }
return nil
}
code := ExtractCmdExitCode(err)