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  }