Source file src/os/path_test.go

     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  	"path/filepath"
    11  	"runtime"
    12  	"syscall"
    13  	"testing"
    14  )
    15  
    16  var isReadonlyError = func(error) bool { return false }
    17  
    18  func TestMkdirAll(t *testing.T) {
    19  	testMaybeRooted(t, func(t *testing.T, r *Root) {
    20  		mkdirAll := MkdirAll
    21  		create := Create
    22  		if r != nil {
    23  			mkdirAll = r.MkdirAll
    24  			create = r.Create
    25  		}
    26  
    27  		path := "_TestMkdirAll_/dir/./dir2"
    28  		err := mkdirAll(path, 0777)
    29  		if err != nil {
    30  			t.Fatalf("MkdirAll %q: %s", path, err)
    31  		}
    32  
    33  		// Already exists, should succeed.
    34  		err = mkdirAll(path, 0777)
    35  		if err != nil {
    36  			t.Fatalf("MkdirAll %q (second time): %s", path, err)
    37  		}
    38  
    39  		// Make file.
    40  		fpath := path + "/file"
    41  		f, err := create(fpath)
    42  		if err != nil {
    43  			t.Fatalf("create %q: %s", fpath, err)
    44  		}
    45  		defer f.Close()
    46  
    47  		// Can't make directory named after file.
    48  		err = mkdirAll(fpath, 0777)
    49  		if err == nil {
    50  			t.Fatalf("MkdirAll %q: no error", fpath)
    51  		}
    52  		perr, ok := err.(*PathError)
    53  		if !ok {
    54  			t.Fatalf("MkdirAll %q returned %T, not *PathError", fpath, err)
    55  		}
    56  		if filepath.Clean(perr.Path) != filepath.Clean(fpath) {
    57  			t.Fatalf("MkdirAll %q returned wrong error path: %q not %q", fpath, filepath.Clean(perr.Path), filepath.Clean(fpath))
    58  		}
    59  
    60  		// Can't make subdirectory of file.
    61  		ffpath := fpath + "/subdir"
    62  		err = mkdirAll(ffpath, 0777)
    63  		if err == nil {
    64  			t.Fatalf("MkdirAll %q: no error", ffpath)
    65  		}
    66  		perr, ok = err.(*PathError)
    67  		if !ok {
    68  			t.Fatalf("MkdirAll %q returned %T, not *PathError", ffpath, err)
    69  		}
    70  		if filepath.Clean(perr.Path) != filepath.Clean(fpath) {
    71  			t.Fatalf("MkdirAll %q returned wrong error path: %q not %q", ffpath, filepath.Clean(perr.Path), filepath.Clean(fpath))
    72  		}
    73  
    74  		if runtime.GOOS == "windows" {
    75  			path := `_TestMkdirAll_\dir\.\dir2\`
    76  			err := mkdirAll(path, 0777)
    77  			if err != nil {
    78  				t.Fatalf("MkdirAll %q: %s", path, err)
    79  			}
    80  		}
    81  	})
    82  }
    83  
    84  func TestMkdirAllAbsPath(t *testing.T) {
    85  	t.Parallel()
    86  	tmpDir := t.TempDir()
    87  	path := filepath.Join(tmpDir, "/a/b/c")
    88  	if err := MkdirAll(path, 0o777); err != nil {
    89  		t.Fatal(err)
    90  	}
    91  	st, err := Stat(path)
    92  	if err != nil {
    93  		t.Fatal(err)
    94  	}
    95  	if !st.IsDir() {
    96  		t.Fatalf("after MkdirAll(%q, 0o777), %q is not a directory", path, path)
    97  	}
    98  }
    99  
   100  func TestMkdirAllWithSymlink(t *testing.T) {
   101  	testenv.MustHaveSymlink(t)
   102  	t.Parallel()
   103  
   104  	tmpDir := t.TempDir()
   105  	dir := tmpDir + "/dir"
   106  	if err := Mkdir(dir, 0755); err != nil {
   107  		t.Fatalf("Mkdir %s: %s", dir, err)
   108  	}
   109  
   110  	link := tmpDir + "/link"
   111  	if err := Symlink("dir", link); err != nil {
   112  		t.Fatalf("Symlink %s: %s", link, err)
   113  	}
   114  
   115  	path := link + "/foo"
   116  	if err := MkdirAll(path, 0755); err != nil {
   117  		t.Errorf("MkdirAll %q: %s", path, err)
   118  	}
   119  }
   120  
   121  func TestMkdirAllAtSlash(t *testing.T) {
   122  	switch runtime.GOOS {
   123  	case "android", "ios", "plan9", "windows":
   124  		t.Skipf("skipping on %s", runtime.GOOS)
   125  	}
   126  	if testenv.Builder() == "" {
   127  		t.Skipf("skipping non-hermetic test outside of Go builders")
   128  	}
   129  
   130  	RemoveAll("/_go_os_test")
   131  	const dir = "/_go_os_test/dir"
   132  	err := MkdirAll(dir, 0777)
   133  	if err != nil {
   134  		pathErr, ok := err.(*PathError)
   135  		// common for users not to be able to write to /
   136  		if ok && (pathErr.Err == syscall.EACCES || isReadonlyError(pathErr.Err)) {
   137  			t.Skipf("could not create %v: %v", dir, err)
   138  		}
   139  		t.Fatalf(`MkdirAll "/_go_os_test/dir": %v, %s`, err, pathErr.Err)
   140  	}
   141  	RemoveAll("/_go_os_test")
   142  }
   143  

View as plain text