• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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