diff --git a/staging/src/k8s.io/mount-utils/mount_helper_common.go b/staging/src/k8s.io/mount-utils/mount_helper_common.go index 0183f6e71c7..69b2849d00d 100644 --- a/staging/src/k8s.io/mount-utils/mount_helper_common.go +++ b/staging/src/k8s.io/mount-utils/mount_helper_common.go @@ -146,7 +146,7 @@ func removePathIfNotMountPoint(mountPath string, mounter Interface, extensiveMou // removePath attempts to remove the directory. Returns nil if the directory was removed or does not exist. func removePath(mountPath string) error { - klog.Warningf("Warning: deleting mount path %q", mountPath) + klog.Warningf("Warning: deleting path %q", mountPath) err := os.Remove(mountPath) if os.IsNotExist(err) { klog.V(4).Infof("%q does not exist", mountPath) diff --git a/staging/src/k8s.io/mount-utils/mount_linux.go b/staging/src/k8s.io/mount-utils/mount_linux.go index 0ae9cd4b208..333035fd562 100644 --- a/staging/src/k8s.io/mount-utils/mount_linux.go +++ b/staging/src/k8s.io/mount-utils/mount_linux.go @@ -233,6 +233,11 @@ func detectSystemd() bool { // When possible, we will trust umount's message and avoid doing our own mount point checks. // More info: https://github.com/util-linux/util-linux/blob/v2.2/mount/umount.c#L179 func detectSafeNotMountedBehavior() bool { + return detectSafeNotMountedBehaviorWithExec(utilexec.New()) +} + +// detectSafeNotMountedBehaviorWithExec is for testing with FakeExec. +func detectSafeNotMountedBehaviorWithExec(exec utilexec.Interface) bool { if _, err := exec.LookPath("umount"); err != nil { klog.V(2).Infof("Failed to locate umount executable to detect safe 'not mounted' behavior") return false diff --git a/staging/src/k8s.io/mount-utils/mount_linux_test.go b/staging/src/k8s.io/mount-utils/mount_linux_test.go index 72547b91d94..dc5939041ab 100644 --- a/staging/src/k8s.io/mount-utils/mount_linux_test.go +++ b/staging/src/k8s.io/mount-utils/mount_linux_test.go @@ -20,11 +20,15 @@ limitations under the License. package mount import ( + "errors" "io/ioutil" "os" "reflect" "strings" "testing" + + utilexec "k8s.io/utils/exec" + testexec "k8s.io/utils/exec/testing" ) func TestReadProcMountsFrom(t *testing.T) { @@ -545,3 +549,66 @@ func mountArgsContainOption(t *testing.T, mountArgs []string, option string) boo return strings.Contains(mountArgs[optionsIndex], option) } + +func TestDetectSafeNotMountedBehavior(t *testing.T) { + // example output for umount from util-linux 2.30.2 + notMountedOutput := "umount: /foo: not mounted." + + // Arrange + testcases := []struct { + fakeCommandAction testexec.FakeCommandAction + expectedSafe bool + }{ + { + fakeCommandAction: makeFakeCommandAction(notMountedOutput, errors.New("any error")), + expectedSafe: true, + }, + { + fakeCommandAction: makeFakeCommandAction(notMountedOutput, nil), + expectedSafe: false, + }, + { + fakeCommandAction: makeFakeCommandAction("any output", nil), + expectedSafe: false, + }, + { + fakeCommandAction: makeFakeCommandAction("any output", errors.New("any error")), + expectedSafe: false, + }, + } + + for _, v := range testcases { + // Prepare + fakeexec := &testexec.FakeExec{ + LookPathFunc: func(s string) (string, error) { + return "fake-umount", nil + }, + CommandScript: []testexec.FakeCommandAction{v.fakeCommandAction}, + } + // Act + isSafe := detectSafeNotMountedBehaviorWithExec(fakeexec) + // Assert + if isSafe != v.expectedSafe { + var adj string + if v.expectedSafe { + adj = "safe" + } else { + adj = "unsafe" + } + t.Errorf("Expected to detect %s umount behavior, but did not", adj) + } + } +} + +func makeFakeCommandAction(stdout string, err error) testexec.FakeCommandAction { + c := testexec.FakeCmd{ + CombinedOutputScript: []testexec.FakeAction{ + func() ([]byte, []byte, error) { + return []byte(stdout), nil, err + }, + }, + } + return func(cmd string, args ...string) utilexec.Cmd { + return testexec.InitFakeCmd(&c, cmd, args...) + } +}