Commit 06bdd52f authored by Bryan C. Mills's avatar Bryan C. Mills

os: use an actual RemoveAll failure in TestRemoveAllWithMoreErrorThanReqSize

Previously we injected an error, and the injection points were
(empirically) not realistic on some platforms.

Instead, we now make the directory read-only, which (on most
platforms) suffices to prevent the removal of its files.

Fixes #35117
Updates #29921

Change-Id: Ica4e2818566f8c14df3eed7c3b8de5c0abeb6963
Reviewed-on: https://go-review.googlesource.com/c/go/+/203502Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 66f78e9d
...@@ -9,4 +9,3 @@ package os ...@@ -9,4 +9,3 @@ package os
var Atime = atime var Atime = atime
var LstatP = &lstat var LstatP = &lstat
var ErrWriteAtInAppendMode = errWriteAtInAppendMode var ErrWriteAtInAppendMode = errWriteAtInAppendMode
var RemoveAllTestHook = &removeAllTestHook
...@@ -153,7 +153,6 @@ func removeAllFrom(parent *File, base string) error { ...@@ -153,7 +153,6 @@ func removeAllFrom(parent *File, base string) error {
// Remove the directory itself. // Remove the directory itself.
unlinkError := unix.Unlinkat(parentFd, base, unix.AT_REMOVEDIR) unlinkError := unix.Unlinkat(parentFd, base, unix.AT_REMOVEDIR)
unlinkError = removeAllTestHook(unlinkError)
if unlinkError == nil || IsNotExist(unlinkError) { if unlinkError == nil || IsNotExist(unlinkError) {
return nil return nil
} }
......
...@@ -124,7 +124,6 @@ func removeAll(path string) error { ...@@ -124,7 +124,6 @@ func removeAll(path string) error {
// Remove directory. // Remove directory.
err1 := Remove(path) err1 := Remove(path)
err1 = removeAllTestHook(err1)
if err1 == nil || IsNotExist(err1) { if err1 == nil || IsNotExist(err1) {
return nil return nil
} }
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
package os_test package os_test
import ( import (
"errors"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
. "os" . "os"
...@@ -413,14 +412,6 @@ func TestRemoveAllWithMoreErrorThanReqSize(t *testing.T) { ...@@ -413,14 +412,6 @@ func TestRemoveAllWithMoreErrorThanReqSize(t *testing.T) {
t.Skip("skipping in short mode") t.Skip("skipping in short mode")
} }
defer func(oldHook func(error) error) {
*RemoveAllTestHook = oldHook
}(*RemoveAllTestHook)
*RemoveAllTestHook = func(err error) error {
return errors.New("error from RemoveAllTestHook")
}
tmpDir, err := ioutil.TempDir("", "TestRemoveAll-") tmpDir, err := ioutil.TempDir("", "TestRemoveAll-")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
...@@ -429,7 +420,7 @@ func TestRemoveAllWithMoreErrorThanReqSize(t *testing.T) { ...@@ -429,7 +420,7 @@ func TestRemoveAllWithMoreErrorThanReqSize(t *testing.T) {
path := filepath.Join(tmpDir, "_TestRemoveAllWithMoreErrorThanReqSize_") path := filepath.Join(tmpDir, "_TestRemoveAllWithMoreErrorThanReqSize_")
// Make directory with 1025 files and remove. // Make directory with 1025 read-only files.
if err := MkdirAll(path, 0777); err != nil { if err := MkdirAll(path, 0777); err != nil {
t.Fatalf("MkdirAll %q: %s", path, err) t.Fatalf("MkdirAll %q: %s", path, err)
} }
...@@ -442,13 +433,40 @@ func TestRemoveAllWithMoreErrorThanReqSize(t *testing.T) { ...@@ -442,13 +433,40 @@ func TestRemoveAllWithMoreErrorThanReqSize(t *testing.T) {
fd.Close() fd.Close()
} }
// This call should not hang // Make the parent directory read-only. On some platforms, this is what
if err := RemoveAll(path); err == nil { // prevents os.Remove from removing the files within that directory.
t.Fatal("Want error from RemoveAllTestHook, got nil") if err := Chmod(path, 0555); err != nil {
t.Fatal(err)
} }
defer Chmod(path, 0755)
// We hook to inject error, but the actual files must be deleted // This call should not hang, even on a platform that disallows file deletion
if _, err := Lstat(path); err == nil { // from read-only directories.
t.Fatal("directory must be deleted even with removeAllTetHook run") err = RemoveAll(path)
if Getuid() == 0 {
// On many platforms, root can remove files from read-only directories.
return
}
if err == nil {
t.Fatal("RemoveAll(<read-only directory>) = nil; want error")
}
dir, err := Open(path)
if err != nil {
t.Fatal(err)
}
defer dir.Close()
if runtime.GOOS == "windows" {
// Marking a directory in Windows does not prevent the os package from
// creating or removing files within it.
// (See https://golang.org/issue/35042.)
return
}
names, _ := dir.Readdirnames(1025)
if len(names) < 1025 {
t.Fatalf("RemoveAll(<read-only directory>) unexpectedly removed %d read-only files from that directory", 1025-len(names))
} }
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment