From 433566655a72738d3f2f700c4134226a88e6293d Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Thu, 18 Sep 2014 14:48:47 -0400 Subject: os: avoid error result when dir is removed out from under RemoveAll Fixes issue 7776. LGTM=bradfitz R=golang-codereviews, bradfitz CC=golang-codereviews, r https://codereview.appspot.com/145860043 --- src/os/os_test.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'src/os/os_test.go') diff --git a/src/os/os_test.go b/src/os/os_test.go index 0224c9b01..7a2849741 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,44 @@ 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) { + 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() +} -- cgit v1.2.1