Home | History | Annotate | Download | only in osutil
      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 
      4 package osutil
      5 
      6 import (
      7 	"fmt"
      8 	"io/ioutil"
      9 	"os"
     10 	"path/filepath"
     11 	"strconv"
     12 	"sync"
     13 	"testing"
     14 )
     15 
     16 func 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