git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/singleinstance/singleinstance_unix_test.go (about) 1 //go:build !windows 2 3 package singleinstance_test 4 5 import ( 6 "os" 7 "syscall" 8 "testing" 9 10 "git.sr.ht/~pingoo/stdx/singleinstance" 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/require" 13 ) 14 15 func TestSingle(t *testing.T) { 16 s := singleinstance.New("unittest") 17 require.NotNil(t, s) 18 19 t.Logf("Lockfile: %s", s.Lockfile()) 20 21 err := s.Lock() 22 assert.NoError(t, err) 23 24 assert.EqualError(t, checkLock(s), singleinstance.ErrAlreadyRunning.Error()) 25 26 err = s.Unlock() 27 assert.NoError(t, err) 28 } 29 30 func checkLock(s *singleinstance.SingleInstance) error { 31 f, err := os.OpenFile(s.Lockfile(), os.O_RDONLY, 0600) 32 if err != nil { 33 return err 34 } 35 36 // try to obtain an exclusive lock with the PPID 37 38 flock := syscall.Flock_t{ 39 Type: syscall.F_WRLCK, 40 Pid: int32(os.Getppid()), 41 } 42 43 if err := syscall.FcntlFlock(f.Fd(), syscall.F_SETLK, &flock); err != nil { 44 return singleinstance.ErrAlreadyRunning 45 } 46 47 return nil 48 }