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 }