func()

in integration/utils/exec.go [465:534]


func (s *MountState) TearDown(t *testing.T) error {
	t.Helper()

	var firstErr error
	setFirstErr := func(err error) {
		if firstErr == nil {
			firstErr = err
		}
	}

	unix.Umask(s.oldMask)

	if s.Stdin != nil {
		if err := s.Stdin.Close(); err != nil {
			t.Errorf("Failed to close sandboxfs's stdin pipe: %v", err)
			setFirstErr(err)
		}

		s.Stdin = nil
	}

	if s.Cmd != nil {
		// Calling Unmount on the mount point causes the running sandboxfs process to
		// stop serving and to exit cleanly.  Note that Unmount is not an unmount(2)
		// system call: this can be run as an unprivileged user, so we needn't check for
		// root privileges.
		//
		// Note that we must be resilient to unmount failures as we can get transient
		// "resource busy" errors.  While our tests should not be keeping files open on the
		// mount point after they terminate (that'd be a bug), the operating system may
		// interfere with us and access the file system under the hood.  If that happens, we
		// get a business error even when we think the mount point is not busy.  For
		// example, on macOS, the Finder may decide to obtain information about the mount
		// point and, if it does that while we try to unmount it, we get an unexpected
		// error.
		unmount := func() error { return Unmount(s.mountPoint) }
		if err := retry(unmount, "waiting for file system to be unmounted", shutdownDeadlineSeconds); err != nil {
			t.Errorf("Failed to unmount sandboxfs instance during teardown: %v", err)
			setFirstErr(err)
		}

		timer := time.AfterFunc(shutdownDeadlineSeconds*time.Second, func() {
			s.Cmd.Process.Kill()
		})
		err := s.Cmd.Wait()
		timer.Stop()
		if err != nil {
			t.Errorf("sandboxfs did not exit successfully during teardown: %v", err)
			setFirstErr(err)
		}

		s.Cmd = nil
	}

	if t.Failed() {
		if s.stdout != nil {
			fmt.Fprintf(os.Stderr, "sandboxfs stdout was:\n%s", s.stdout.String())
		}
		if s.stderr != nil {
			fmt.Fprintf(os.Stderr, "sandboxfs stderr was:\n%s", s.stderr.String())
		}
	}

	if err := os.RemoveAll(s.tempDir); err != nil {
		t.Errorf("Failed to remove temporary directory %s during teardown: %v", s.tempDir, err)
		setFirstErr(err)
	}

	return firstErr
}