github.com/mutagen-io/mutagen@v0.18.0-rc1/pkg/filesystem/directory_test.go (about) 1 package filesystem 2 3 import ( 4 "os" 5 "path/filepath" 6 "runtime" 7 "testing" 8 "unicode/utf8" 9 ) 10 11 // TestPathSeparatorSingleByte verifies that the platform path separator rune is 12 // encoded as a single byte in UTF-8. We rely on this assumption for high 13 // performance in ensureValidName. 14 func TestPathSeparatorSingleByte(t *testing.T) { 15 if utf8.RuneLen(os.PathSeparator) != 1 { 16 t.Fatal("OS path separator does not have single-byte UTF-8 encoding") 17 } 18 } 19 20 func TestDirectoryContentsNotExist(t *testing.T) { 21 if _, err := DirectoryContentsByPath("/does/not/exist"); err == nil { 22 t.Error("directory listing succeedeed for non-existent path") 23 } 24 } 25 26 func TestDirectoryContentsFile(t *testing.T) { 27 // Create an empty temporary file and defer its cleanup. 28 file, err := os.CreateTemp("", "mutagen_filesystem") 29 if err != nil { 30 t.Fatal("unable to create temporary file:", err) 31 } else if err = file.Close(); err != nil { 32 t.Error("unable to close temporary file:", err) 33 } 34 defer os.Remove(file.Name()) 35 36 // Ensure that directory listing fails. 37 if _, err := DirectoryContentsByPath(file.Name()); err == nil { 38 t.Error("directory listing succeedeed for non-directory path") 39 } 40 } 41 42 func TestDirectoryContentsGOROOT(t *testing.T) { 43 if contents, err := DirectoryContentsByPath(runtime.GOROOT()); err != nil { 44 t.Fatal("directory listing failed for GOROOT:", err) 45 } else if contents == nil { 46 t.Fatal("directory contents nil for GOROOT") 47 } 48 } 49 50 // TestNonEmptyDirectoryRemovalFailure tests that removal of a non-empty 51 // directory results in failure. 52 func TestNonEmptyDirectoryRemovalFailure(t *testing.T) { 53 // Create a handle for a temporary directory (that will be removed 54 // automatically) and defer its closure. 55 directory, _, err := OpenDirectory(t.TempDir(), false) 56 if err != nil { 57 t.Fatal("unable to open directory handle:", err) 58 } 59 defer directory.Close() 60 61 // Create a directory that will serve as our target. 62 if err := directory.CreateDirectory("target"); err != nil { 63 t.Fatal("unable to create target directory:", err) 64 } 65 66 // Create content inside the directory. 67 if target, err := directory.OpenDirectory("target"); err != nil { 68 t.Fatal("unable to open target directory:", err) 69 } else if err = target.CreateDirectory("content"); err != nil { 70 target.Close() 71 t.Fatal("unable to create content in target directory:", err) 72 } else if err = target.Close(); err != nil { 73 t.Fatal("unable to close target directory:", err) 74 } 75 76 // Attempt to remove the target directory. 77 if directory.RemoveDirectory("target") == nil { 78 t.Error("able to remove non-empty directory") 79 } 80 } 81 82 // TestDirectorySymbolicLinkRemoval tests that removal of symbolic links that 83 // point to directories works as expected. 84 func TestDirectorySymbolicLinkRemoval(t *testing.T) { 85 // Create a temporary directory (that will be automatically removed). 86 temporaryDirectoryPath := t.TempDir() 87 88 // Create a handle for the temporary directory and defer its closure. 89 directory, _, err := OpenDirectory(temporaryDirectoryPath, false) 90 if err != nil { 91 t.Fatal("unable to open directory handle:", err) 92 } 93 defer directory.Close() 94 95 // Create a directory that will serve as our target. 96 if err := directory.CreateDirectory("target"); err != nil { 97 t.Fatal("unable to create target directory:", err) 98 } 99 100 // Open the target directory and defer its closure. 101 target, err := directory.OpenDirectory("target") 102 if err != nil { 103 t.Fatal("unable to open target directory:", err) 104 } 105 defer target.Close() 106 107 // Create content within the target. 108 if err := target.CreateDirectory("content"); err != nil { 109 t.Fatal("unable to create content in target directory:", err) 110 } 111 112 // Create a symbolic link to the target. 113 if err := directory.CreateSymbolicLink("link", "target"); err != nil { 114 t.Fatal("unable to create symbolic link:", err) 115 } 116 117 // Remove the symbolic link. 118 if err := directory.RemoveSymbolicLink("link"); err != nil { 119 t.Fatal("unable to remove symbolic link:", err) 120 } 121 122 // Grab the target metadata to ensure that it still exists. As an additional 123 // sanity check, also ensure that the content path still exists, but do so 124 // using path-based access. 125 if _, err := directory.ReadContentMetadata("target"); err != nil { 126 t.Error("unable to read target metadata:", err) 127 } else if _, err = os.Lstat(filepath.Join(temporaryDirectoryPath, "target", "content")); err != nil { 128 t.Error("unable to read target content metadata:", err) 129 } 130 }