aboutsummaryrefslogtreecommitdiff
path: root/tests/test_helpers/helpers.go
diff options
context:
space:
mode:
authorJakob Unterwurzacher2019-01-01 22:04:36 +0100
committerJakob Unterwurzacher2019-01-01 22:27:10 +0100
commite276e255dc7d88099f35c890b704ce64117f731e (patch)
tree99c9cbe2ac8a0aaafb7ba92921dcb52c6ee12bcc /tests/test_helpers/helpers.go
parent10de105c13e4ef512fe83b8c1074fc453f3e70ff (diff)
tests: split mount_unmount.go from helpers.go
With the FD leak logic, the mount/unmount functions have become complex enough to give them their own file.
Diffstat (limited to 'tests/test_helpers/helpers.go')
-rw-r--r--tests/test_helpers/helpers.go178
1 files changed, 0 insertions, 178 deletions
diff --git a/tests/test_helpers/helpers.go b/tests/test_helpers/helpers.go
index 1982b96..c6a4d6e 100644
--- a/tests/test_helpers/helpers.go
+++ b/tests/test_helpers/helpers.go
@@ -6,15 +6,12 @@ import (
"encoding/hex"
"encoding/json"
"fmt"
- "io"
"io/ioutil"
"log"
"net"
"os"
"os/exec"
- "os/signal"
"path/filepath"
- "runtime"
"syscall"
"testing"
"time"
@@ -46,16 +43,6 @@ var DefaultPlainDir string
// DefaultCipherDir is TmpDir + "/default-cipher"
var DefaultCipherDir string
-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
// xattr tests cannot run on tmpfs and use /var/tmp instead of /tmp.
@@ -165,141 +152,6 @@ func InitFS(t *testing.T, extraArgs ...string) string {
return dir
}
-// Mount CIPHERDIR "c" on PLAINDIR "p"
-// Creates "p" if it does not exist.
-func Mount(c string, p string, showOutput bool, extraArgs ...string) error {
- args := []string{"-q", "-wpanic", "-nosyslog", "-fg", fmt.Sprintf("-notifypid=%d", os.Getpid())}
- args = append(args, extraArgs...)
- //args = append(args, "-fusedebug")
- //args = append(args, "-d")
- args = append(args, c, p)
-
- if _, err := os.Stat(p); err != nil {
- err = os.Mkdir(p, 0777)
- if err != nil {
- return err
- }
- }
-
- cmd := exec.Command(GocryptfsBinary, args...)
- if showOutput {
- // The Go test logic waits for our stdout to close, and when we share
- // it with the subprocess, it will wait for it to close it as well.
- // Use an intermediate pipe so the tests do not hang when unmouting
- // fails.
- pr, pw, err := os.Pipe()
- if err != nil {
- return err
- }
- // We can close the fd after cmd.Run() has executed
- defer pw.Close()
- cmd.Stderr = pw
- cmd.Stdout = pw
- go func() {
- io.Copy(os.Stdout, pr)
- pr.Close()
- }()
- }
-
- // Two things can happen:
- // 1) The mount fails and the process exits
- // 2) The mount succeeds and the process sends us USR1
- chanExit := make(chan error, 1)
- chanUsr1 := make(chan os.Signal, 1)
- signal.Notify(chanUsr1, syscall.SIGUSR1)
-
- // Start the process and save the PID
- err := cmd.Start()
- if err != nil {
- return err
- }
- pid := cmd.Process.Pid
-
- // Wait for exit or usr1
- go func() {
- chanExit <- cmd.Wait()
- }()
- select {
- case err := <-chanExit:
- return err
- case <-chanUsr1:
- // noop
- case <-time.After(1 * time.Second):
- log.Panicf("Timeout waiting for process %d", pid)
- }
-
- // Save PID and open FDs
- MountInfo[p] = mountInfo{pid, ListFds(pid)}
- return nil
-}
-
-// MountOrExit calls Mount() and exits on failure.
-func MountOrExit(c string, p string, extraArgs ...string) {
- err := Mount(c, p, true, extraArgs...)
- if err != nil {
- fmt.Printf("mount failed: %v\n", err)
- os.Exit(1)
- }
-}
-
-// MountOrFatal calls Mount() and calls t.Fatal() on failure.
-func MountOrFatal(t *testing.T, c string, p string, extraArgs ...string) {
- err := Mount(c, p, true, extraArgs...)
- if err != nil {
- t.Fatal(fmt.Errorf("mount failed: %v", err))
- }
-}
-
-// UnmountPanic tries to umount "dir" and panics on error.
-func UnmountPanic(dir string) {
- err := UnmountErr(dir)
- if err != nil {
- fmt.Printf("UnmountPanic: %v. Running lsof %s\n", err, dir)
- cmd := exec.Command("lsof", dir)
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
- cmd.Run()
- panic("UnmountPanic: unmount failed: " + err.Error())
- }
-}
-
-// 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.
- // If we try to unmount before Gnome is done, the unmount fails with
- // "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)
- fmt.Printf("UnmountErr: got exit code %d, retrying (%d/%d)\n", code, i, max)
- time.Sleep(100 * time.Millisecond)
- }
- return err
-}
-
// Md5fn returns an md5 string for file "filename"
func Md5fn(filename string) string {
buf, err := ioutil.ReadFile(filename)
@@ -504,33 +356,3 @@ func ExtractCmdExitCode(err error) int {
log.Panicf("could not decode error %#v", err)
return 0
}
-
-// ListFds lists the open file descriptors for process "pid". Pass pid=0 for
-// ourselves.
-func ListFds(pid int) []string {
- // We need /proc to get the list of fds for other processes. Only exists
- // on Linux.
- if runtime.GOOS != "linux" && pid > 0 {
- return nil
- }
- // Both Linux and MacOS have /dev/fd
- dir := "/dev/fd"
- if pid > 0 {
- dir = fmt.Sprintf("/proc/%d/fd", pid)
- }
- f, err := os.Open(dir)
- if err != nil {
- log.Panic(err)
- }
- defer f.Close()
- names, err := f.Readdirnames(0)
- if err != nil {
- log.Panic(err)
- }
- for i, n := range names {
- // Note: Readdirnames filters "." and ".."
- target, _ := os.Readlink(dir + "/" + n)
- names[i] = n + "=" + target
- }
- return names
-}