1// Copyright 2015 syzkaller project authors. All rights reserved. 2// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. 3 4package osutil 5 6import ( 7 "fmt" 8 "io/ioutil" 9 "os" 10 "path/filepath" 11 "strconv" 12 "sync" 13 "testing" 14) 15 16func TestProcessTempDir(t *testing.T) { 17 for try := 0; try < 10; try++ { 18 func() { 19 tmp, err := ioutil.TempDir("", "syz") 20 if err != nil { 21 t.Fatalf("failed to create a temp dir: %v", err) 22 } 23 defer os.RemoveAll(tmp) 24 const P = 16 25 // Pre-create half of the instances with stale pid. 26 var dirs []string 27 for i := 0; i < P/2; i++ { 28 dir, err := ProcessTempDir(tmp) 29 if err != nil { 30 t.Fatalf("failed to create process temp dir") 31 } 32 dirs = append(dirs, dir) 33 } 34 for _, dir := range dirs { 35 if err := WriteFile(filepath.Join(dir, ".pid"), []byte(strconv.Itoa(999999999))); err != nil { 36 t.Fatalf("failed to write pid file: %v", err) 37 } 38 } 39 // Now request a bunch of instances concurrently. 40 done := make(chan error) 41 allDirs := make(map[string]bool) 42 var mu sync.Mutex 43 for p := 0; p < P; p++ { 44 go func() { 45 dir, err := ProcessTempDir(tmp) 46 if err != nil { 47 done <- fmt.Errorf("failed to create temp dir: %v", err) 48 return 49 } 50 mu.Lock() 51 present := allDirs[dir] 52 allDirs[dir] = true 53 mu.Unlock() 54 if present { 55 done <- fmt.Errorf("duplicate dir %v", dir) 56 return 57 } 58 done <- nil 59 }() 60 } 61 for p := 0; p < P; p++ { 62 if err := <-done; err != nil { 63 t.Error(err) 64 } 65 } 66 }() 67 } 68} 69