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  }