diff --git a/pkg/util/mount/BUILD b/pkg/util/mount/BUILD index 3b2a78a565..9040cd93b2 100644 --- a/pkg/util/mount/BUILD +++ b/pkg/util/mount/BUILD @@ -102,6 +102,7 @@ go_test( ] + select({ "@io_bazel_rules_go//go/platform:linux": [ "//vendor/github.com/golang/glog:go_default_library", + "//vendor/k8s.io/utils/exec:go_default_library", ], "@io_bazel_rules_go//go/platform:windows": [ "//vendor/github.com/stretchr/testify/assert:go_default_library", diff --git a/pkg/util/mount/mount_linux_test.go b/pkg/util/mount/mount_linux_test.go index fe7b7028d5..d6b3c497c2 100644 --- a/pkg/util/mount/mount_linux_test.go +++ b/pkg/util/mount/mount_linux_test.go @@ -25,10 +25,12 @@ import ( "os" "path/filepath" "reflect" + "strconv" + "strings" "syscall" "testing" - "strconv" + "k8s.io/utils/exec" "github.com/golang/glog" ) @@ -1680,3 +1682,110 @@ func TestFindExistingPrefix(t *testing.T) { os.RemoveAll(base) } } + +func TestGetFileType(t *testing.T) { + mounter := Mounter{"fake/path", false} + + testCase := []struct { + name string + expectedType FileType + setUp func() (string, string, error) + }{ + { + "Directory Test", + FileTypeDirectory, + func() (string, string, error) { + tempDir, err := ioutil.TempDir("", "test-get-filetype-") + return tempDir, tempDir, err + }, + }, + { + "File Test", + FileTypeFile, + func() (string, string, error) { + tempFile, err := ioutil.TempFile("", "test-get-filetype") + if err != nil { + return "", "", err + } + tempFile.Close() + return tempFile.Name(), tempFile.Name(), nil + }, + }, + { + "Socket Test", + FileTypeSocket, + func() (string, string, error) { + tempDir, err := ioutil.TempDir("", "test-get-filetype-") + if err != nil { + return "", "", err + } + tempSocketFile, err := createSocketFile(tempDir) + return tempSocketFile, tempDir, err + }, + }, + { + "Block Device Test", + FileTypeBlockDev, + func() (string, string, error) { + tempDir, err := ioutil.TempDir("", "test-get-filetype-") + if err != nil { + return "", "", err + } + + tempBlockFile := filepath.Join(tempDir, "test_blk_dev") + outputBytes, err := exec.New().Command("mknod", tempBlockFile, "b", "89", "1").CombinedOutput() + if err != nil { + err = fmt.Errorf("%v: %s ", err, outputBytes) + } + return tempBlockFile, tempDir, err + }, + }, + { + "Character Device Test", + FileTypeCharDev, + func() (string, string, error) { + tempDir, err := ioutil.TempDir("", "test-get-filetype-") + if err != nil { + return "", "", err + } + + tempCharFile := filepath.Join(tempDir, "test_char_dev") + outputBytes, err := exec.New().Command("mknod", tempCharFile, "c", "89", "1").CombinedOutput() + if err != nil { + err = fmt.Errorf("%v: %s ", err, outputBytes) + } + return tempCharFile, tempDir, err + }, + }, + } + + for idx, tc := range testCase { + path, cleanUpPath, err := tc.setUp() + if err != nil { + // Locally passed, but upstream CI is not friendly to create such device files + // Leave "Operation not permitted" out, which can be covered in an e2e test + if isOperationNotPermittedError(err) { + continue + } + t.Fatalf("[%d-%s] unexpected error : %v", idx, tc.name, err) + } + if len(cleanUpPath) > 0 { + defer os.RemoveAll(cleanUpPath) + } + + fileType, err := mounter.GetFileType(path) + if err != nil { + t.Fatalf("[%d-%s] unexpected error : %v", idx, tc.name, err) + } + if fileType != tc.expectedType { + t.Fatalf("[%d-%s] expected %s, but got %s", idx, tc.name, tc.expectedType, fileType) + } + } +} + +func isOperationNotPermittedError(err error) bool { + if strings.Contains(err.Error(), "Operation not permitted") { + return true + } + return false +} diff --git a/pkg/util/mount/mount_windows_test.go b/pkg/util/mount/mount_windows_test.go index e31217e975..12fa5152f5 100644 --- a/pkg/util/mount/mount_windows_test.go +++ b/pkg/util/mount/mount_windows_test.go @@ -20,6 +20,7 @@ package mount import ( "fmt" + "io/ioutil" "os" "os/exec" "path/filepath" @@ -551,3 +552,52 @@ func TestPathWithinBase(t *testing.T) { test.fullPath, test.basePath, result, test.expectedResult) } } + +func TestGetFileType(t *testing.T) { + mounter := New("fake/path") + + testCase := []struct { + name string + expectedType FileType + setUp func() (string, string, error) + }{ + { + "Directory Test", + FileTypeDirectory, + func() (string, string, error) { + tempDir, err := ioutil.TempDir("", "test-get-filetype-") + return tempDir, tempDir, err + }, + }, + { + "File Test", + FileTypeFile, + func() (string, string, error) { + tempFile, err := ioutil.TempFile("", "test-get-filetype") + if err != nil { + return "", "", err + } + tempFile.Close() + return tempFile.Name(), tempFile.Name(), nil + }, + }, + } + + for idx, tc := range testCase { + path, cleanUpPath, err := tc.setUp() + if err != nil { + t.Fatalf("[%d-%s] unexpected error : %v", idx, tc.name, err) + } + if len(cleanUpPath) > 0 { + defer os.RemoveAll(cleanUpPath) + } + + fileType, err := mounter.GetFileType(path) + if err != nil { + t.Fatalf("[%d-%s] unexpected error : %v", idx, tc.name, err) + } + if fileType != tc.expectedType { + t.Fatalf("[%d-%s] expected %s, but got %s", idx, tc.name, tc.expectedType, fileType) + } + } +}