src.elv.sh@v0.21.0-dev.0.20240515223629-06979efb9a2a/pkg/mods/unix/umask_test.go (about) 1 //go:build unix 2 3 package unix 4 5 import ( 6 "os" 7 "strconv" 8 "sync" 9 "testing" 10 11 "src.elv.sh/pkg/must" 12 "src.elv.sh/pkg/testutil" 13 ) 14 15 func TestUmaskGetRace(t *testing.T) { 16 testutil.Umask(t, 0o22) 17 testutil.InTempDir(t) 18 19 // An old implementation of UmaskVariable.Get had a bug where it will 20 // briefly set the umask to 0, which can impact files created concurrently. 21 for i := 0; i < 100; i++ { 22 filename := strconv.Itoa(i) 23 runParallel( 24 func() { 25 // Calling UmaskVariable.Get is much quicker than creating a 26 // file, so do it in a loop to increase the chance of triggering 27 // a race condition. 28 for j := 0; j < 100; j++ { 29 UmaskVariable{}.Get() 30 } 31 }, 32 func() { 33 must.OK(create(filename, 0o666)) 34 }) 35 36 perm := must.OK1(os.Stat(filename)).Mode().Perm() 37 if perm != 0o644 { 38 t.Errorf("got perm %o, want 0o644 (run %d)", perm, i) 39 } 40 } 41 } 42 43 func runParallel(funcs ...func()) { 44 var wg sync.WaitGroup 45 wg.Add(len(funcs)) 46 for _, f := range funcs { 47 f := f 48 go func() { 49 f() 50 wg.Done() 51 }() 52 } 53 wg.Wait() 54 } 55 56 func create(name string, perm os.FileMode) error { 57 file, err := os.OpenFile(name, os.O_CREATE, perm) 58 if err == nil { 59 file.Close() 60 } 61 return err 62 }