github.com/geraldss/go/src@v0.0.0-20210511222824-ac7d0ebfc235/os/path_test.go (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package os_test
     6  
     7  import (
     8  	"internal/testenv"
     9  	"os"
    10  	. "os"
    11  	"path/filepath"
    12  	"runtime"
    13  	"syscall"
    14  	"testing"
    15  )
    16  
    17  var isReadonlyError = func(error) bool { return false }
    18  
    19  func TestMkdirAll(t *testing.T) {
    20  	tmpDir := TempDir()
    21  	path := tmpDir + "/_TestMkdirAll_/dir/./dir2"
    22  	err := MkdirAll(path, 0777)
    23  	if err != nil {
    24  		t.Fatalf("MkdirAll %q: %s", path, err)
    25  	}
    26  	defer RemoveAll(tmpDir + "/_TestMkdirAll_")
    27  
    28  	// Already exists, should succeed.
    29  	err = MkdirAll(path, 0777)
    30  	if err != nil {
    31  		t.Fatalf("MkdirAll %q (second time): %s", path, err)
    32  	}
    33  
    34  	// Make file.
    35  	fpath := path + "/file"
    36  	f, err := Create(fpath)
    37  	if err != nil {
    38  		t.Fatalf("create %q: %s", fpath, err)
    39  	}
    40  	defer f.Close()
    41  
    42  	// Can't make directory named after file.
    43  	err = MkdirAll(fpath, 0777)
    44  	if err == nil {
    45  		t.Fatalf("MkdirAll %q: no error", fpath)
    46  	}
    47  	perr, ok := err.(*PathError)
    48  	if !ok {
    49  		t.Fatalf("MkdirAll %q returned %T, not *PathError", fpath, err)
    50  	}
    51  	if filepath.Clean(perr.Path) != filepath.Clean(fpath) {
    52  		t.Fatalf("MkdirAll %q returned wrong error path: %q not %q", fpath, filepath.Clean(perr.Path), filepath.Clean(fpath))
    53  	}
    54  
    55  	// Can't make subdirectory of file.
    56  	ffpath := fpath + "/subdir"
    57  	err = MkdirAll(ffpath, 0777)
    58  	if err == nil {
    59  		t.Fatalf("MkdirAll %q: no error", ffpath)
    60  	}
    61  	perr, ok = err.(*PathError)
    62  	if !ok {
    63  		t.Fatalf("MkdirAll %q returned %T, not *PathError", ffpath, err)
    64  	}
    65  	if filepath.Clean(perr.Path) != filepath.Clean(fpath) {
    66  		t.Fatalf("MkdirAll %q returned wrong error path: %q not %q", ffpath, filepath.Clean(perr.Path), filepath.Clean(fpath))
    67  	}
    68  
    69  	if runtime.GOOS == "windows" {
    70  		path := tmpDir + `\_TestMkdirAll_\dir\.\dir2\`
    71  		err := MkdirAll(path, 0777)
    72  		if err != nil {
    73  			t.Fatalf("MkdirAll %q: %s", path, err)
    74  		}
    75  	}
    76  }
    77  
    78  func TestMkdirAllWithSymlink(t *testing.T) {
    79  	testenv.MustHaveSymlink(t)
    80  
    81  	tmpDir, err := os.MkdirTemp("", "TestMkdirAllWithSymlink-")
    82  	if err != nil {
    83  		t.Fatal(err)
    84  	}
    85  	defer RemoveAll(tmpDir)
    86  
    87  	dir := tmpDir + "/dir"
    88  	err = Mkdir(dir, 0755)
    89  	if err != nil {
    90  		t.Fatalf("Mkdir %s: %s", dir, err)
    91  	}
    92  
    93  	link := tmpDir + "/link"
    94  	err = Symlink("dir", link)
    95  	if err != nil {
    96  		t.Fatalf("Symlink %s: %s", link, err)
    97  	}
    98  
    99  	path := link + "/foo"
   100  	err = MkdirAll(path, 0755)
   101  	if err != nil {
   102  		t.Errorf("MkdirAll %q: %s", path, err)
   103  	}
   104  }
   105  
   106  func TestMkdirAllAtSlash(t *testing.T) {
   107  	switch runtime.GOOS {
   108  	case "android", "plan9", "windows":
   109  		t.Skipf("skipping on %s", runtime.GOOS)
   110  	case "darwin", "ios":
   111  		switch runtime.GOARCH {
   112  		case "arm64":
   113  			t.Skipf("skipping on darwin/arm64, mkdir returns EPERM")
   114  		}
   115  	}
   116  	RemoveAll("/_go_os_test")
   117  	const dir = "/_go_os_test/dir"
   118  	err := MkdirAll(dir, 0777)
   119  	if err != nil {
   120  		pathErr, ok := err.(*PathError)
   121  		// common for users not to be able to write to /
   122  		if ok && (pathErr.Err == syscall.EACCES || isReadonlyError(pathErr.Err)) {
   123  			t.Skipf("could not create %v: %v", dir, err)
   124  		}
   125  		t.Fatalf(`MkdirAll "/_go_os_test/dir": %v, %s`, err, pathErr.Err)
   126  	}
   127  	RemoveAll("/_go_os_test")
   128  }