github.com/tcnksm/go@v0.0.0-20141208075154-439b32936367/src/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  	"io/ioutil"
     9  	. "os"
    10  	"path/filepath"
    11  	"runtime"
    12  	"syscall"
    13  	"testing"
    14  )
    15  
    16  func TestMkdirAll(t *testing.T) {
    17  	tmpDir := TempDir()
    18  	path := tmpDir + "/_TestMkdirAll_/dir/./dir2"
    19  	err := MkdirAll(path, 0777)
    20  	if err != nil {
    21  		t.Fatalf("MkdirAll %q: %s", path, err)
    22  	}
    23  	defer RemoveAll(tmpDir + "/_TestMkdirAll_")
    24  
    25  	// Already exists, should succeed.
    26  	err = MkdirAll(path, 0777)
    27  	if err != nil {
    28  		t.Fatalf("MkdirAll %q (second time): %s", path, err)
    29  	}
    30  
    31  	// Make file.
    32  	fpath := path + "/file"
    33  	f, err := Create(fpath)
    34  	if err != nil {
    35  		t.Fatalf("create %q: %s", fpath, err)
    36  	}
    37  	defer f.Close()
    38  
    39  	// Can't make directory named after file.
    40  	err = MkdirAll(fpath, 0777)
    41  	if err == nil {
    42  		t.Fatalf("MkdirAll %q: no error", fpath)
    43  	}
    44  	perr, ok := err.(*PathError)
    45  	if !ok {
    46  		t.Fatalf("MkdirAll %q returned %T, not *PathError", fpath, err)
    47  	}
    48  	if filepath.Clean(perr.Path) != filepath.Clean(fpath) {
    49  		t.Fatalf("MkdirAll %q returned wrong error path: %q not %q", fpath, filepath.Clean(perr.Path), filepath.Clean(fpath))
    50  	}
    51  
    52  	// Can't make subdirectory of file.
    53  	ffpath := fpath + "/subdir"
    54  	err = MkdirAll(ffpath, 0777)
    55  	if err == nil {
    56  		t.Fatalf("MkdirAll %q: no error", ffpath)
    57  	}
    58  	perr, ok = err.(*PathError)
    59  	if !ok {
    60  		t.Fatalf("MkdirAll %q returned %T, not *PathError", ffpath, err)
    61  	}
    62  	if filepath.Clean(perr.Path) != filepath.Clean(fpath) {
    63  		t.Fatalf("MkdirAll %q returned wrong error path: %q not %q", ffpath, filepath.Clean(perr.Path), filepath.Clean(fpath))
    64  	}
    65  
    66  	if runtime.GOOS == "windows" {
    67  		path := tmpDir + `\_TestMkdirAll_\dir\.\dir2\`
    68  		err := MkdirAll(path, 0777)
    69  		if err != nil {
    70  			t.Fatalf("MkdirAll %q: %s", path, err)
    71  		}
    72  	}
    73  }
    74  
    75  func TestRemoveAll(t *testing.T) {
    76  	tmpDir := TempDir()
    77  	// Work directory.
    78  	path := tmpDir + "/_TestRemoveAll_"
    79  	fpath := path + "/file"
    80  	dpath := path + "/dir"
    81  
    82  	// Make directory with 1 file and remove.
    83  	if err := MkdirAll(path, 0777); err != nil {
    84  		t.Fatalf("MkdirAll %q: %s", path, err)
    85  	}
    86  	fd, err := Create(fpath)
    87  	if err != nil {
    88  		t.Fatalf("create %q: %s", fpath, err)
    89  	}
    90  	fd.Close()
    91  	if err = RemoveAll(path); err != nil {
    92  		t.Fatalf("RemoveAll %q (first): %s", path, err)
    93  	}
    94  	if _, err = Lstat(path); err == nil {
    95  		t.Fatalf("Lstat %q succeeded after RemoveAll (first)", path)
    96  	}
    97  
    98  	// Make directory with file and subdirectory and remove.
    99  	if err = MkdirAll(dpath, 0777); err != nil {
   100  		t.Fatalf("MkdirAll %q: %s", dpath, err)
   101  	}
   102  	fd, err = Create(fpath)
   103  	if err != nil {
   104  		t.Fatalf("create %q: %s", fpath, err)
   105  	}
   106  	fd.Close()
   107  	fd, err = Create(dpath + "/file")
   108  	if err != nil {
   109  		t.Fatalf("create %q: %s", fpath, err)
   110  	}
   111  	fd.Close()
   112  	if err = RemoveAll(path); err != nil {
   113  		t.Fatalf("RemoveAll %q (second): %s", path, err)
   114  	}
   115  	if _, err := Lstat(path); err == nil {
   116  		t.Fatalf("Lstat %q succeeded after RemoveAll (second)", path)
   117  	}
   118  
   119  	// Determine if we should run the following test.
   120  	testit := true
   121  	if runtime.GOOS == "windows" {
   122  		// Chmod is not supported under windows.
   123  		testit = false
   124  	} else {
   125  		// Test fails as root.
   126  		testit = Getuid() != 0
   127  	}
   128  	if testit {
   129  		// Make directory with file and subdirectory and trigger error.
   130  		if err = MkdirAll(dpath, 0777); err != nil {
   131  			t.Fatalf("MkdirAll %q: %s", dpath, err)
   132  		}
   133  
   134  		for _, s := range []string{fpath, dpath + "/file1", path + "/zzz"} {
   135  			fd, err = Create(s)
   136  			if err != nil {
   137  				t.Fatalf("create %q: %s", s, err)
   138  			}
   139  			fd.Close()
   140  		}
   141  		if err = Chmod(dpath, 0); err != nil {
   142  			t.Fatalf("Chmod %q 0: %s", dpath, err)
   143  		}
   144  
   145  		// No error checking here: either RemoveAll
   146  		// will or won't be able to remove dpath;
   147  		// either way we want to see if it removes fpath
   148  		// and path/zzz.  Reasons why RemoveAll might
   149  		// succeed in removing dpath as well include:
   150  		//	* running as root
   151  		//	* running on a file system without permissions (FAT)
   152  		RemoveAll(path)
   153  		Chmod(dpath, 0777)
   154  
   155  		for _, s := range []string{fpath, path + "/zzz"} {
   156  			if _, err = Lstat(s); err == nil {
   157  				t.Fatalf("Lstat %q succeeded after partial RemoveAll", s)
   158  			}
   159  		}
   160  	}
   161  	if err = RemoveAll(path); err != nil {
   162  		t.Fatalf("RemoveAll %q after partial RemoveAll: %s", path, err)
   163  	}
   164  	if _, err = Lstat(path); err == nil {
   165  		t.Fatalf("Lstat %q succeeded after RemoveAll (final)", path)
   166  	}
   167  }
   168  
   169  func TestMkdirAllWithSymlink(t *testing.T) {
   170  	switch runtime.GOOS {
   171  	case "nacl", "plan9":
   172  		t.Skipf("skipping on %s", runtime.GOOS)
   173  	case "windows":
   174  		if !supportsSymlinks {
   175  			t.Skipf("skipping on %s", runtime.GOOS)
   176  		}
   177  	}
   178  
   179  	tmpDir, err := ioutil.TempDir("", "TestMkdirAllWithSymlink-")
   180  	if err != nil {
   181  		t.Fatal(err)
   182  	}
   183  	defer RemoveAll(tmpDir)
   184  
   185  	dir := tmpDir + "/dir"
   186  	err = Mkdir(dir, 0755)
   187  	if err != nil {
   188  		t.Fatalf("Mkdir %s: %s", dir, err)
   189  	}
   190  
   191  	link := tmpDir + "/link"
   192  	err = Symlink("dir", link)
   193  	if err != nil {
   194  		t.Fatalf("Symlink %s: %s", link, err)
   195  	}
   196  
   197  	path := link + "/foo"
   198  	err = MkdirAll(path, 0755)
   199  	if err != nil {
   200  		t.Errorf("MkdirAll %q: %s", path, err)
   201  	}
   202  }
   203  
   204  func TestMkdirAllAtSlash(t *testing.T) {
   205  	switch runtime.GOOS {
   206  	case "android", "plan9", "windows":
   207  		t.Skipf("skipping on %s", runtime.GOOS)
   208  	}
   209  	RemoveAll("/_go_os_test")
   210  	err := MkdirAll("/_go_os_test/dir", 0777)
   211  	if err != nil {
   212  		pathErr, ok := err.(*PathError)
   213  		// common for users not to be able to write to /
   214  		if ok && pathErr.Err == syscall.EACCES {
   215  			return
   216  		}
   217  		t.Fatalf(`MkdirAll "/_go_os_test/dir": %v`, err)
   218  	}
   219  	RemoveAll("/_go_os_test")
   220  }