summaryrefslogtreecommitdiff
path: root/src/os/os_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/os/os_test.go')
-rw-r--r--src/os/os_test.go50
1 files changed, 50 insertions, 0 deletions
diff --git a/src/os/os_test.go b/src/os/os_test.go
index 0224c9b01..973cc3a7b 100644
--- a/src/os/os_test.go
+++ b/src/os/os_test.go
@@ -18,6 +18,7 @@ import (
"runtime"
"sort"
"strings"
+ "sync"
"syscall"
"testing"
"text/template"
@@ -1403,3 +1404,52 @@ func TestNilFileMethods(t *testing.T) {
}
}
}
+
+func mkdirTree(t *testing.T, root string, level, max int) {
+ if level >= max {
+ return
+ }
+ level++
+ for i := 'a'; i < 'c'; i++ {
+ dir := filepath.Join(root, string(i))
+ if err := Mkdir(dir, 0700); err != nil {
+ t.Fatal(err)
+ }
+ mkdirTree(t, dir, level, max)
+ }
+}
+
+// Test that simultaneous RemoveAll do not report an error.
+// As long as it gets removed, we should be happy.
+func TestRemoveAllRace(t *testing.T) {
+ if runtime.GOOS == "windows" {
+ // Windows has very strict rules about things like
+ // removing directories while someone else has
+ // them open. The racing doesn't work out nicely
+ // like it does on Unix.
+ t.Skip("skipping on windows")
+ }
+
+ n := runtime.GOMAXPROCS(16)
+ defer runtime.GOMAXPROCS(n)
+ root, err := ioutil.TempDir("", "issue")
+ if err != nil {
+ t.Fatal(err)
+ }
+ mkdirTree(t, root, 1, 6)
+ hold := make(chan struct{})
+ var wg sync.WaitGroup
+ for i := 0; i < 4; i++ {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ <-hold
+ err := RemoveAll(root)
+ if err != nil {
+ t.Errorf("unexpected error: %T, %q", err, err)
+ }
+ }()
+ }
+ close(hold) // let workers race to remove root
+ wg.Wait()
+}