github.com/maxnasonov/afero@v1.8.4/symlink_test.go (about)

     1  package afero
     2  
     3  import (
     4  	"os"
     5  	"path/filepath"
     6  	"strings"
     7  	"testing"
     8  )
     9  
    10  func TestSymlinkIfPossible(t *testing.T) {
    11  	wd, _ := os.Getwd()
    12  	defer func() {
    13  		os.Chdir(wd)
    14  	}()
    15  
    16  	osFs := &OsFs{}
    17  
    18  	workDir, err := TempDir(osFs, "", "afero-symlink")
    19  	if err != nil {
    20  		t.Fatal(err)
    21  	}
    22  
    23  	defer func() {
    24  		osFs.RemoveAll(workDir)
    25  	}()
    26  
    27  	memWorkDir := "/sym"
    28  
    29  	memFs := NewMemMapFs()
    30  	overlayFs1 := &CopyOnWriteFs{base: osFs, layer: memFs}
    31  	overlayFs2 := &CopyOnWriteFs{base: memFs, layer: osFs}
    32  	overlayFsMemOnly := &CopyOnWriteFs{base: memFs, layer: NewMemMapFs()}
    33  	basePathFs := &BasePathFs{source: osFs, path: workDir}
    34  	basePathFsMem := &BasePathFs{source: memFs, path: memWorkDir}
    35  	roFs := &ReadOnlyFs{source: osFs}
    36  	roFsMem := &ReadOnlyFs{source: memFs}
    37  
    38  	pathFileMem := filepath.Join(memWorkDir, "aferom.txt")
    39  	osPath := filepath.Join(workDir, "afero.txt")
    40  
    41  	WriteFile(osFs, osPath, []byte("Hi, Afero!"), 0777)
    42  	WriteFile(memFs, filepath.Join(pathFileMem), []byte("Hi, Afero!"), 0777)
    43  
    44  	testLink := func(l Linker, source, destination string, output *string) {
    45  		if fs, ok := l.(Fs); ok {
    46  			dir := filepath.Dir(destination)
    47  			if dir != "" {
    48  				fs.MkdirAll(dir, 0777)
    49  			}
    50  		}
    51  
    52  		err := l.SymlinkIfPossible(source, destination)
    53  		if (err == nil) && (output != nil) {
    54  			t.Fatalf("Error creating symlink, succeeded when expecting error %v", *output)
    55  		} else if (err != nil) && (output == nil) {
    56  			t.Fatalf("Error creating symlink, expected success, got %v", err)
    57  		} else if err != nil && err.Error() != *output && !strings.HasSuffix(err.Error(), *output) {
    58  			t.Fatalf("Error creating symlink, expected error '%v', instead got output '%v'", *output, err)
    59  		} else {
    60  			// test passed, if expecting a successful link, check the link with lstat if able
    61  			if output == nil {
    62  				if lst, ok := l.(Lstater); ok {
    63  					_, ok, err := lst.LstatIfPossible(destination)
    64  					if !ok {
    65  						if err != nil {
    66  							t.Fatalf("Error calling lstat on file after successful link, got: %v", err)
    67  						} else {
    68  							t.Fatalf("Error calling lstat on file after successful link, result didn't use lstat (not link)")
    69  						}
    70  						return
    71  					}
    72  				}
    73  			}
    74  		}
    75  	}
    76  
    77  	notSupported := ErrNoSymlink.Error()
    78  
    79  	testLink(osFs, osPath, filepath.Join(workDir, "os/link.txt"), nil)
    80  	testLink(overlayFs1, osPath, filepath.Join(workDir, "overlay/link1.txt"), &notSupported)
    81  	testLink(overlayFs2, pathFileMem, filepath.Join(workDir, "overlay2/link2.txt"), nil)
    82  	testLink(overlayFsMemOnly, pathFileMem, filepath.Join(memWorkDir, "overlay3/link.txt"), &notSupported)
    83  	testLink(basePathFs, "afero.txt", "basepath/link.txt", nil)
    84  	testLink(basePathFsMem, pathFileMem, "link/file.txt", &notSupported)
    85  	testLink(roFs, osPath, filepath.Join(workDir, "ro/link.txt"), &notSupported)
    86  	testLink(roFsMem, pathFileMem, filepath.Join(memWorkDir, "ro/link.txt"), &notSupported)
    87  }
    88  
    89  func TestReadlinkIfPossible(t *testing.T) {
    90  	wd, _ := os.Getwd()
    91  	defer func() {
    92  		os.Chdir(wd)
    93  	}()
    94  
    95  	osFs := &OsFs{}
    96  
    97  	workDir, err := TempDir(osFs, "", "afero-readlink")
    98  	if err != nil {
    99  		t.Fatal(err)
   100  	}
   101  
   102  	defer func() {
   103  		osFs.RemoveAll(workDir)
   104  	}()
   105  
   106  	memWorkDir := "/read"
   107  
   108  	memFs := NewMemMapFs()
   109  	overlayFs1 := &CopyOnWriteFs{base: osFs, layer: memFs}
   110  	overlayFs2 := &CopyOnWriteFs{base: memFs, layer: osFs}
   111  	overlayFsMemOnly := &CopyOnWriteFs{base: memFs, layer: NewMemMapFs()}
   112  	basePathFs := &BasePathFs{source: osFs, path: workDir}
   113  	basePathFsMem := &BasePathFs{source: memFs, path: memWorkDir}
   114  	roFs := &ReadOnlyFs{source: osFs}
   115  	roFsMem := &ReadOnlyFs{source: memFs}
   116  
   117  	pathFileMem := filepath.Join(memWorkDir, "aferom.txt")
   118  	osPath := filepath.Join(workDir, "afero.txt")
   119  
   120  	WriteFile(osFs, osPath, []byte("Hi, Afero!"), 0777)
   121  	WriteFile(memFs, filepath.Join(pathFileMem), []byte("Hi, Afero!"), 0777)
   122  
   123  	createLink := func(l Linker, source, destination string) error {
   124  		if fs, ok := l.(Fs); ok {
   125  			dir := filepath.Dir(destination)
   126  			if dir != "" {
   127  				fs.MkdirAll(dir, 0777)
   128  			}
   129  		}
   130  
   131  		return l.SymlinkIfPossible(source, destination)
   132  	}
   133  
   134  	testRead := func(r LinkReader, name string, output *string) {
   135  		_, err := r.ReadlinkIfPossible(name)
   136  		if (err != nil) && (output == nil) {
   137  			t.Fatalf("Error reading link, expected success, got error: %v", err)
   138  		} else if (err == nil) && (output != nil) {
   139  			t.Fatalf("Error reading link, succeeded when expecting error: %v", *output)
   140  		} else if err != nil && err.Error() != *output && !strings.HasSuffix(err.Error(), *output) {
   141  			t.Fatalf("Error reading link, expected error '%v', instead received '%v'", *output, err)
   142  		}
   143  	}
   144  
   145  	notSupported := ErrNoReadlink.Error()
   146  
   147  	err = createLink(osFs, osPath, filepath.Join(workDir, "os/link.txt"))
   148  	if err != nil {
   149  		t.Fatal("Error creating test link: ", err)
   150  	}
   151  
   152  	testRead(osFs, filepath.Join(workDir, "os/link.txt"), nil)
   153  	testRead(overlayFs1, filepath.Join(workDir, "os/link.txt"), nil)
   154  	testRead(overlayFs2, filepath.Join(workDir, "os/link.txt"), nil)
   155  	testRead(overlayFsMemOnly, pathFileMem, &notSupported)
   156  	testRead(basePathFs, "os/link.txt", nil)
   157  	testRead(basePathFsMem, pathFileMem, &notSupported)
   158  	testRead(roFs, filepath.Join(workDir, "os/link.txt"), nil)
   159  	testRead(roFsMem, pathFileMem, &notSupported)
   160  }