github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/pkg/osutil/fileutil_test.go (about)

     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  	"path/filepath"
     9  	"strconv"
    10  	"sync"
    11  	"testing"
    12  )
    13  
    14  func TestProcessTempDir(t *testing.T) {
    15  	for try := 0; try < 10; try++ {
    16  		func() {
    17  			tmp := t.TempDir()
    18  			const P = 16
    19  			// Pre-create half of the instances with stale pid.
    20  			var dirs []string
    21  			for i := 0; i < P/2; i++ {
    22  				dir, err := ProcessTempDir(tmp)
    23  				if err != nil {
    24  					t.Fatalf("failed to create process temp dir")
    25  				}
    26  				dirs = append(dirs, dir)
    27  			}
    28  			for _, dir := range dirs {
    29  				if err := WriteFile(filepath.Join(dir, ".pid"), []byte(strconv.Itoa(999999999))); err != nil {
    30  					t.Fatalf("failed to write pid file: %v", err)
    31  				}
    32  			}
    33  			// Now request a bunch of instances concurrently.
    34  			done := make(chan error)
    35  			allDirs := make(map[string]bool)
    36  			var mu sync.Mutex
    37  			for p := 0; p < P; p++ {
    38  				go func() {
    39  					dir, err := ProcessTempDir(tmp)
    40  					if err != nil {
    41  						done <- fmt.Errorf("failed to create temp dir: %w", err)
    42  						return
    43  					}
    44  					mu.Lock()
    45  					present := allDirs[dir]
    46  					allDirs[dir] = true
    47  					mu.Unlock()
    48  					if present {
    49  						done <- fmt.Errorf("duplicate dir %v", dir)
    50  						return
    51  					}
    52  					done <- nil
    53  				}()
    54  			}
    55  			for p := 0; p < P; p++ {
    56  				if err := <-done; err != nil {
    57  					t.Error(err)
    58  				}
    59  			}
    60  		}()
    61  	}
    62  }