github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/os/removeall_test.go (about) 1 // Copyright 2018 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 "fmt" 9 "io/ioutil" 10 . "os" 11 "path/filepath" 12 "runtime" 13 "strings" 14 "testing" 15 ) 16 17 func TestRemoveAll(t *testing.T) { 18 tmpDir, err := ioutil.TempDir("", "TestRemoveAll-") 19 if err != nil { 20 t.Fatal(err) 21 } 22 defer RemoveAll(tmpDir) 23 24 if err := RemoveAll(""); err != nil { 25 t.Errorf("RemoveAll(\"\"): %v; want nil", err) 26 } 27 28 file := filepath.Join(tmpDir, "file") 29 path := filepath.Join(tmpDir, "_TestRemoveAll_") 30 fpath := filepath.Join(path, "file") 31 dpath := filepath.Join(path, "dir") 32 33 // Make a regular file and remove 34 fd, err := Create(file) 35 if err != nil { 36 t.Fatalf("create %q: %s", file, err) 37 } 38 fd.Close() 39 if err = RemoveAll(file); err != nil { 40 t.Fatalf("RemoveAll %q (first): %s", file, err) 41 } 42 if _, err = Lstat(file); err == nil { 43 t.Fatalf("Lstat %q succeeded after RemoveAll (first)", file) 44 } 45 46 // Make directory with 1 file and remove. 47 if err := MkdirAll(path, 0777); err != nil { 48 t.Fatalf("MkdirAll %q: %s", path, err) 49 } 50 fd, err = Create(fpath) 51 if err != nil { 52 t.Fatalf("create %q: %s", fpath, err) 53 } 54 fd.Close() 55 if err = RemoveAll(path); err != nil { 56 t.Fatalf("RemoveAll %q (second): %s", path, err) 57 } 58 if _, err = Lstat(path); err == nil { 59 t.Fatalf("Lstat %q succeeded after RemoveAll (second)", path) 60 } 61 62 // Make directory with file and subdirectory and remove. 63 if err = MkdirAll(dpath, 0777); err != nil { 64 t.Fatalf("MkdirAll %q: %s", dpath, err) 65 } 66 fd, err = Create(fpath) 67 if err != nil { 68 t.Fatalf("create %q: %s", fpath, err) 69 } 70 fd.Close() 71 fd, err = Create(dpath + "/file") 72 if err != nil { 73 t.Fatalf("create %q: %s", fpath, err) 74 } 75 fd.Close() 76 if err = RemoveAll(path); err != nil { 77 t.Fatalf("RemoveAll %q (third): %s", path, err) 78 } 79 if _, err := Lstat(path); err == nil { 80 t.Fatalf("Lstat %q succeeded after RemoveAll (third)", path) 81 } 82 83 // Determine if we should run the following test. 84 testit := true 85 if runtime.GOOS == "windows" { 86 // Chmod is not supported under windows. 87 testit = false 88 } else { 89 // Test fails as root. 90 testit = Getuid() != 0 91 } 92 if testit { 93 // Make directory with file and subdirectory and trigger error. 94 if err = MkdirAll(dpath, 0777); err != nil { 95 t.Fatalf("MkdirAll %q: %s", dpath, err) 96 } 97 98 for _, s := range []string{fpath, dpath + "/file1", path + "/zzz"} { 99 fd, err = Create(s) 100 if err != nil { 101 t.Fatalf("create %q: %s", s, err) 102 } 103 fd.Close() 104 } 105 if err = Chmod(dpath, 0); err != nil { 106 t.Fatalf("Chmod %q 0: %s", dpath, err) 107 } 108 109 // No error checking here: either RemoveAll 110 // will or won't be able to remove dpath; 111 // either way we want to see if it removes fpath 112 // and path/zzz. Reasons why RemoveAll might 113 // succeed in removing dpath as well include: 114 // * running as root 115 // * running on a file system without permissions (FAT) 116 RemoveAll(path) 117 Chmod(dpath, 0777) 118 119 for _, s := range []string{fpath, path + "/zzz"} { 120 if _, err = Lstat(s); err == nil { 121 t.Fatalf("Lstat %q succeeded after partial RemoveAll", s) 122 } 123 } 124 } 125 if err = RemoveAll(path); err != nil { 126 t.Fatalf("RemoveAll %q after partial RemoveAll: %s", path, err) 127 } 128 if _, err = Lstat(path); err == nil { 129 t.Fatalf("Lstat %q succeeded after RemoveAll (final)", path) 130 } 131 } 132 133 // Test RemoveAll on a large directory. 134 func TestRemoveAllLarge(t *testing.T) { 135 if testing.Short() { 136 t.Skip("skipping in short mode") 137 } 138 139 tmpDir, err := ioutil.TempDir("", "TestRemoveAll-") 140 if err != nil { 141 t.Fatal(err) 142 } 143 defer RemoveAll(tmpDir) 144 145 path := filepath.Join(tmpDir, "_TestRemoveAllLarge_") 146 147 // Make directory with 1000 files and remove. 148 if err := MkdirAll(path, 0777); err != nil { 149 t.Fatalf("MkdirAll %q: %s", path, err) 150 } 151 for i := 0; i < 1000; i++ { 152 fpath := fmt.Sprintf("%s/file%d", path, i) 153 fd, err := Create(fpath) 154 if err != nil { 155 t.Fatalf("create %q: %s", fpath, err) 156 } 157 fd.Close() 158 } 159 if err := RemoveAll(path); err != nil { 160 t.Fatalf("RemoveAll %q: %s", path, err) 161 } 162 if _, err := Lstat(path); err == nil { 163 t.Fatalf("Lstat %q succeeded after RemoveAll", path) 164 } 165 } 166 167 func TestRemoveAllLongPath(t *testing.T) { 168 switch runtime.GOOS { 169 case "aix", "darwin", "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris": 170 break 171 default: 172 t.Skip("skipping for not implemented platforms") 173 } 174 175 prevDir, err := Getwd() 176 if err != nil { 177 t.Fatalf("Could not get wd: %s", err) 178 } 179 180 startPath, err := ioutil.TempDir("", "TestRemoveAllLongPath-") 181 if err != nil { 182 t.Fatalf("Could not create TempDir: %s", err) 183 } 184 defer RemoveAll(startPath) 185 186 err = Chdir(startPath) 187 if err != nil { 188 t.Fatalf("Could not chdir %s: %s", startPath, err) 189 } 190 191 // Removing paths with over 4096 chars commonly fails 192 for i := 0; i < 41; i++ { 193 name := strings.Repeat("a", 100) 194 195 err = Mkdir(name, 0755) 196 if err != nil { 197 t.Fatalf("Could not mkdir %s: %s", name, err) 198 } 199 200 err = Chdir(name) 201 if err != nil { 202 t.Fatalf("Could not chdir %s: %s", name, err) 203 } 204 } 205 206 err = Chdir(prevDir) 207 if err != nil { 208 t.Fatalf("Could not chdir %s: %s", prevDir, err) 209 } 210 211 err = RemoveAll(startPath) 212 if err != nil { 213 t.Errorf("RemoveAll could not remove long file path %s: %s", startPath, err) 214 } 215 } 216 217 func TestRemoveAllDot(t *testing.T) { 218 prevDir, err := Getwd() 219 if err != nil { 220 t.Fatalf("Could not get wd: %s", err) 221 } 222 tempDir, err := ioutil.TempDir("", "TestRemoveAllDot-") 223 if err != nil { 224 t.Fatalf("Could not create TempDir: %s", err) 225 } 226 defer RemoveAll(tempDir) 227 228 err = Chdir(tempDir) 229 if err != nil { 230 t.Fatalf("Could not chdir to tempdir: %s", err) 231 } 232 233 err = RemoveAll(".") 234 if err == nil { 235 t.Errorf("RemoveAll succeed to remove .") 236 } 237 238 err = Chdir(prevDir) 239 if err != nil { 240 t.Fatalf("Could not chdir %s: %s", prevDir, err) 241 } 242 } 243 244 func TestRemoveAllDotDot(t *testing.T) { 245 t.Parallel() 246 247 tempDir, err := ioutil.TempDir("", "TestRemoveAllDotDot-") 248 if err != nil { 249 t.Fatal(err) 250 } 251 defer RemoveAll(tempDir) 252 253 subdir := filepath.Join(tempDir, "x") 254 subsubdir := filepath.Join(subdir, "y") 255 if err := MkdirAll(subsubdir, 0777); err != nil { 256 t.Fatal(err) 257 } 258 if err := RemoveAll(filepath.Join(subsubdir, "..")); err != nil { 259 t.Error(err) 260 } 261 for _, dir := range []string{subsubdir, subdir} { 262 if _, err := Stat(dir); err == nil { 263 t.Errorf("%s: exists after RemoveAll", dir) 264 } 265 } 266 } 267 268 // Issue #29178. 269 func TestRemoveReadOnlyDir(t *testing.T) { 270 t.Parallel() 271 272 tempDir, err := ioutil.TempDir("", "TestRemoveReadOnlyDir-") 273 if err != nil { 274 t.Fatal(err) 275 } 276 defer RemoveAll(tempDir) 277 278 subdir := filepath.Join(tempDir, "x") 279 if err := Mkdir(subdir, 0); err != nil { 280 t.Fatal(err) 281 } 282 283 // If an error occurs make it more likely that removing the 284 // temporary directory will succeed. 285 defer Chmod(subdir, 0777) 286 287 if err := RemoveAll(subdir); err != nil { 288 t.Fatal(err) 289 } 290 291 if _, err := Stat(subdir); err == nil { 292 t.Error("subdirectory was not removed") 293 } 294 } 295 296 // Issue #29983. 297 func TestRemoveAllButReadOnly(t *testing.T) { 298 switch runtime.GOOS { 299 case "nacl", "js", "windows": 300 t.Skipf("skipping test on %s", runtime.GOOS) 301 } 302 303 if Getuid() == 0 { 304 t.Skip("skipping test when running as root") 305 } 306 307 t.Parallel() 308 309 tempDir, err := ioutil.TempDir("", "TestRemoveAllButReadOnly-") 310 if err != nil { 311 t.Fatal(err) 312 } 313 defer RemoveAll(tempDir) 314 315 dirs := []string{ 316 "a", 317 "a/x", 318 "a/x/1", 319 "b", 320 "b/y", 321 "b/y/2", 322 "c", 323 "c/z", 324 "c/z/3", 325 } 326 readonly := []string{ 327 "b", 328 } 329 inReadonly := func(d string) bool { 330 for _, ro := range readonly { 331 if d == ro { 332 return true 333 } 334 dd, _ := filepath.Split(d) 335 if filepath.Clean(dd) == ro { 336 return true 337 } 338 } 339 return false 340 } 341 342 for _, dir := range dirs { 343 if err := Mkdir(filepath.Join(tempDir, dir), 0777); err != nil { 344 t.Fatal(err) 345 } 346 } 347 for _, dir := range readonly { 348 d := filepath.Join(tempDir, dir) 349 if err := Chmod(d, 0555); err != nil { 350 t.Fatal(err) 351 } 352 353 // Defer changing the mode back so that the deferred 354 // RemoveAll(tempDir) can succeed. 355 defer Chmod(d, 0777) 356 } 357 358 if err := RemoveAll(tempDir); err == nil { 359 t.Fatal("RemoveAll succeeded unexpectedly") 360 } 361 362 for _, dir := range dirs { 363 _, err := Stat(filepath.Join(tempDir, dir)) 364 if inReadonly(dir) { 365 if err != nil { 366 t.Errorf("file %q was deleted but should still exist", dir) 367 } 368 } else { 369 if err == nil { 370 t.Errorf("file %q still exists but should have been deleted", dir) 371 } 372 } 373 } 374 }